码迷,mamicode.com
首页 > 编程语言 > 详细

Uva11183-Teen Girl Squad(有向图最小生成树朱刘算法)

时间:2016-07-31 15:51:08      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

解析: 裸的有向图最小生成树

代码

技术分享
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
const int INF=1e9+7;
const int eps=0.0000001;
const int maxn=1005;
struct edge
{
    int u,v,w;
    edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
}E[40005];
int pre[maxn],InEdge[maxn],vis[maxn],id[maxn];
int Dir_MST(int root,int Vcnt,int Ecnt)
{
    int ret=0;
    while(true)
    {
        for(int i=1;i<=Vcnt;i++) InEdge[i]=INF;
        for(int i=1;i<=Ecnt;i++)
        {
            edge& e=E[i];
            int u=e.u,v=e.v,w=e.w;
            if(u==v) continue;
            if(w<InEdge[v]) { InEdge[v]=w; pre[v]=u; } //找最小的指向v的边
        }
        InEdge[root]=0;
        for(int i=1;i<=Vcnt;i++) if(i!=root&&InEdge[i]==INF) return -1;//存在某个点跟整个图分离
        int ID=0;
        for(int i=1;i<=Vcnt;i++) vis[i]=id[i]=-1;
        for(int i=1;i<=Vcnt;i++)
        {
            ret+=InEdge[i];  //把那些边加进答案
            int a=i;
            while(vis[a]!=i&&id[a]==-1&&a!=root){ vis[a]=i; a=pre[a]; }
            if(id[a]==-1&&a!=root)
            {
                ++ID;
                for(int b=pre[a];b!=a;b=pre[b]) id[b]=ID;  //重新编号
                id[a]=ID;
            }
        }
        if(ID==0) return ret;  //找到解
        for(int i=1;i<=Vcnt;i++) if(id[i]==-1) id[i]=++ID; //独立的点编号
        for(int i=1;i<=Ecnt;i++)
        {
            edge& e=E[i];
            int u=e.u,v=e.v;
            e.u=id[u];
            e.v=id[v];
            if(id[u]!=id[v]) e.w-=InEdge[v]; //之前加的那一部分要减掉
        }
        Vcnt=ID;
        root=id[root];
    }
}
int main()
{
    int T,Case=0;
    scanf("%d",&T);
    while(T--)
    {
        int N,M,u,v,w;
        scanf("%d%d",&N,&M);
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            u++; v++;
            E[i]=edge(u,v,w);
        }
        int ans=Dir_MST(1,N,M);
        printf("Case #%d: ",++Case);
        if(ans==-1) printf("Possums!\n");
        else printf("%d\n",ans);
    }
    return 0;
}
View Code

 

Uva11183-Teen Girl Squad(有向图最小生成树朱刘算法)

标签:

原文地址:http://www.cnblogs.com/wust-ouyangli/p/5723025.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!