• HDU2121 Ice_cream’s world II (最小树形图)


    在建图的时候对原图进行加边 建立一个超级源点~

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1014;
    const int maxm=10014;
    const int inf=1e9;
    struct edge {
        int u;
        int v;
        int w;
    }Edge[maxm];
    int pre[maxn];
    int id[maxn];
    int visit[maxn];
    int in[maxn];
    int N,M;
    int root;
    int pos;
    int num;
    void add (int u,int v,int w) {
        Edge[num].u=u;
        Edge[num].v=v;
        Edge[num++].w=w;
    }
    int solve () {
        int ans=0;
        while (1) {
            for (int i=0;i<N;i++) in[i]=inf;
            for (int i=0;i<num;i++) {
                int u=Edge[i].u;
                int v=Edge[i].v;
                if (Edge[i].w<in[v]&&u!=v) {
                    pre[v]=u;
                    in[v]=Edge[i].w;
                    if (u==root) pos=i;
                }
            }
            for (int i=0;i<N;i++) {
                if (i!=root&&in[i]==inf) return -1;
            }
            int tn=0;
            memset(id,-1,sizeof(id));
            memset(visit,-1,sizeof(visit));
            in[root]=0;
            for (int i=0;i<N;i++) {
                ans+=in[i];
                int v=i;
                while (visit[v]!=i&&id[v]==-1&&v!=root) {
                    visit[v]=i;
                    v=pre[v];
                }
                if (v!=root&&id[v]==-1) {
                    for (int u=pre[v];u!=v;u=pre[u]) 
                    id[u]=tn;
                    id[v]=tn++;
                }
            }
            if (tn==0) break;
            for (int i=0;i<N;i++) {
                if (id[i]==-1) id[i]=tn++;
            }
            for (int i=0;i<num;i++) {
                int v=Edge[i].v;
                Edge[i].u=id[Edge[i].u];
                Edge[i].v=id[Edge[i].v];
                if (Edge[i].u!=Edge[i].v) Edge[i].w-=in[v];
            }
            N=tn;
            root=id[root];
        }
        return ans;
    }
    int main () {
        while (~scanf("%d%d",&N,&M)) {
            int sum=0;
            num=0;
            for (int i=0;i<M;i++) {
                int u,v,w;
                scanf ("%d %d %d",&u,&v,&w);
                sum+=w;
                add(u,v,w); 
            }
            sum++;
            for (int i=0;i<N;i++) {
                add(N,i,sum);
            }
            N++;
            root=N-1;
            int ans=solve();
            if (ans==-1||ans>=2*sum) {
                printf ("impossible
    ");
            }
            else printf ("%d %d
    ",ans-sum,pos-M);
            printf ("
    ");
        }
        return 0;
    }
  • 相关阅读:
    项目有大小,生存各有道
    学习Spark——那些让你精疲力尽的坑
    学习Spark——环境搭建(Mac版)
    小程序新能力-个人开发者尝鲜微信小程序
    如何写出好代码
    华为手机nova2s使用第三方字体库
    std::string与std::wstring互相转换
    Steam安装Google Earth VR
    osgearth2.8关于RectangleNodeEditor编辑点不可见的问题
    Qt生成ui文件对应的.h和.cpp文件
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12354047.html
Copyright © 2020-2023  润新知