uva 11183 Teen Girl Squad

题意:

有一个女孩,需要打电话让所有的人知道一个消息,消息可以被每一个知道消息的人传递。

打电话的关系是单向的,每一次电话需要一定的花费。

求出打电话最少的花费或者判断不可能让所有人知道消息。

思路:

最小树形图模板题。

朱刘算法,复杂度O(n^3),n的规模较小。

代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <vector>
  4 using namespace std;
  5 
  6 const int N = 1005;
  7 const int inf = 0x3f3f3f3f;
  8 
  9 struct edge
 10 {
 11     int from,to,cost;
 12     
 13     edge(int a,int b,int c)
 14     {
 15         from = a;
 16         to = b;
 17         cost = c;
 18     }
 19 };
 20 
 21 int in[1005],pre[1005],vis[1005],id[1005];
 22 
 23 vector<edge> es;
 24 
 25 int zhu_liu(int n)
 26 {
 27     int res = 0;
 28     
 29     int root = 0;
 30     
 31     while (1)
 32     {
 33         memset(vis,-1,sizeof(vis));
 34         memset(id,-1,sizeof(id));
 35         memset(in,inf,sizeof(in));
 36         
 37         for (int i = 0;i < es.size();i++)
 38         {
 39             edge e = es[i];
 40             
 41             int to = e.to;
 42             
 43             if (e.from != e.to && e.cost < in[to])
 44             {
 45                 in[to] = e.cost;
 46                 pre[e.to] = e.from;
 47             }
 48         }
 49         
 50         for (int i = 0;i < n;i++)
 51         {
 52             if (i != root && in[i] == inf) return -1;
 53         }
 54         
 55         in[root] = 0;
 56         
 57         int cnt = 0;
 58         
 59         for (int i = 0;i < n;i++)
 60         {
 61             res += in[i];
 62             
 63             int v = i;
 64             
 65             while (vis[v] != i && id[v] == -1 && v != root)
 66             {
 67                 vis[v] = i;
 68                 v = pre[v];
 69             }
 70             
 71             if (id[v] == -1 && v != root)
 72             {
 73                 for (int u = pre[v];u != v;u = pre[u])
 74                 {
 75                     id[u] = cnt;
 76                 }
 77                 
 78                 id[v] = cnt++;
 79             }
 80         }
 81         
 82         if (cnt == 0) break;
 83         
 84         for (int i = 0;i < n;i++)
 85         {
 86             if (id[i] == -1) id[i] = cnt++;
 87         }
 88         
 89         for (int i = 0;i < es.size();i++)
 90         {
 91             edge e = es[i];
 92             
 93             int v = e.to;
 94             
 95             es[i].to = id[es[i].to];
 96             es[i].from = id[es[i].from];
 97             
 98             if (es[i].to != es[i].from) es[i].cost -= in[v];
 99         }
100         
101         root = id[root];
102         n = cnt;
103     }
104     
105     return res;
106 }
107 
108 int main()
109 {
110     int t;
111     
112     int kase = 0;
113     
114     scanf("%d",&t);
115     
116     while (t--)
117     {
118         int n,m;
119         
120         es.clear();
121         
122         scanf("%d%d",&n,&m);
123         
124         for (int i = 0;i < m;i++)
125         {
126             int a,b,c;
127             
128             scanf("%d%d%d",&a,&b,&c);
129             
130             es.push_back(edge(a,b,c));
131         }
132         
133         int ans = zhu_liu(n);
134         
135         printf("Case #%d: ",++kase);
136         
137         if (ans == -1) printf("Possums!\n");
138         else printf("%d\n",ans);
139     }
140     
141     return 0;
142 }

 

posted @ 2018-04-12 17:08  qrfkickit  阅读(250)  评论(0编辑  收藏  举报