HDU 2121 Ice_cream’s world II

无固定根的最小树形图。。。

虚拟一个节点(0号节点),其到其余N个点的边权都为所有M条边的权值和(sum)+1,然后以此为Root跑朱刘算法,最后判断连接到0号节点的节点数目是不是1,若是1输出

输出ans - sum - 1,否则无解。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<stack>
  7 #include<queue>
  8 #include<map>
  9 #include<cstdlib>
 10 #include<cmath>
 11 using namespace std;
 12 #define ll long long
 13 #define pb push_back
 14 const int MAXM = 10005;
 15 const int MAXN = 1005;
 16 int node,n,m,x,y,z,nume,cnt,root,broot,et;
 17 int g[MAXN];
 18 int pre[MAXN];
 19 ll mc[MAXN];
 20 long long sum;
 21 int s[MAXN];
 22 struct edge
 23 {
 24     int u,v,nxt,bu,bv;
 25     ll c;
 26 };
 27 edge e[MAXM];
 28 void init()
 29 {
 30     nume = 1;
 31     memset(g,0,sizeof(g));
 32 }
 33 void addedge(int u,int v,ll c,int judge)
 34 {
 35     if (u == v) return;
 36     if (judge) sum+=c;
 37     ++nume;
 38     e[nume].u = e[nume].bu = u;
 39     e[nume].v = e[nume].bv = v;
 40     e[nume].c = c;
 41     e[nume].nxt = g[u];
 42     g[u] = nume;
 43 }
 44 void find_mincost()
 45 {
 46     memset(pre,0,sizeof(pre));
 47     memset(mc,63,sizeof(mc));
 48     for (int i = 1; i <= nume; i++)
 49         if (e[i].v != e[i].u)
 50     {
 51         if (mc[e[i].v] > e[i].c && e[i].v != root)
 52         {
 53             mc[e[i].v] = e[i].c;
 54             pre[e[i].v] = i;
 55         }
 56     }
 57 }
 58 bool dfs(int x,int y)
 59 {
 60     int z = e[pre[x]].u;
 61     if (z == 0) return 0;
 62     if (s[z] == 0)
 63     {
 64         s[z] = cnt;
 65         if (!dfs(z,y)) s[z] = 0;
 66         else return 1;
 67     }
 68     else return z == y;
 69     return 0;
 70 }
 71 int main()
 72 {
 73     while (scanf("%d%d",&n,&m) != EOF)
 74     {
 75         init();
 76         sum = 0;
 77         for (int i = 1; i <= m; i++)
 78         {
 79             scanf("%d%d%d",&x,&y,&z);
 80             x++; y++;
 81             addedge(x,y,z,1);
 82         }
 83         sum++;
 84         //cout<<sum<<endl;
 85         for (int i = 1; i <= n; i++) addedge(n + 1,i,sum,0);
 86        // cout<<sum<<endl;
 87         n++;
 88        root = n; cnt = n; broot = n; node = 0;
 89        long long ans = 0;
 90        //et = 0;
 91        while (1)
 92        {
 93            et = 0;
 94            find_mincost();//cout<<sum<<endl;
 95            //for (int i = 1; i <= n; i++) cout<<i<<" "<<mc[i]<<" "<<pre[i]<<endl;
 96            for (int i = 1; i <= n; i++)
 97             if (i != root) ans += mc[i];
 98            for (int i = 1; i <= n; i++)
 99            {
100                if (pre[i] == 0) continue;
101                int x = pre[i];
102               // cout<<i<<" "<<e[x].bu<<endl;
103                if (e[x].bu == broot)
104                {
105                    et++;
106                    node = e[x].bv;
107                    //cout<<et<<" "<<node<<"O"<<endl;
108                }
109            }
110            memset(s,0,sizeof(s));
111            cnt = 0;
112            int cir = 0;
113            for (int i = 1; i <= n; i++)
114               if (!s[i])
115               {
116                   cnt++;
117                   s[i] = cnt;
118                   if (dfs(i,i))
119                   {
120                       cir++;
121                   }
122               }
123             //cout<<root<<" "<<cnt<<" "<<cir<<endl;
124             //cout<<m<<endl;
125             if (cir == 0) break;
126             for (int i = 1; i <= nume; i++)
127             {
128                 int x = e[i].u,y = e[i].v;
129                 e[i].u = s[x]; e[i].v = s[y];
130                 if ((e[i].u != e[i].v))
131                 {
132                    //cout<<1<<endl;
133                     e[i].c -= mc[y];
134                 }
135             }
136             //for (int i = 1; i <= m; i++) cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].c<<endl;
137         n = cnt;
138         root = s[root];
139        }
140        //cout<<et<<endl;
141        //cout<<ans<<" "<<sum<<endl;
142        if (et == 1) printf("%I64d %d\n",ans - sum,node - 1);
143        else puts("impossible");
144        printf("\n");
145     }
146     return 0;
147 }
View Code

 

posted @ 2014-03-04 23:41  Mosudas  阅读(120)  评论(0编辑  收藏  举报