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


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

    代码

    #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!
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    File
    Include and Require
    Date and Time
    css3的nth-child选择器使用示例
    document.title
    php获取从百度搜索进入网站的关键词的详细代码
    Iphone手机、安卓手机浏览器控制默认缩放大小的方法
    离线宝调用
    织梦DedeCMS网站地图模板
    禁止选择文本和禁用右键 v3.0
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5723025.html
Copyright © 2020-2023  润新知