TJU 2248. Channel Design 最小树形图
最小树形图,測模版....
Time Limit: 1.0 Seconds Memory Limit: 65536K
Total Runs: 2199 Accepted Runs: 740
In Figure (a), V1 indicates the source of water. Other N-1 nodes in the Figure indicate the farms we need to irrigate. An edge represents you can build a channel between the two nodes, to irrigate the target. The integers indicate the cost of a channel between two nodes.
Figure (b) represents a design of channels with minimum cost.
Input
There are multiple cases, the first line of each case contains two integers N and M (2 ≤ N ≤ 100; 1 ≤ M ≤ 10000), N shows the number of nodes. The following M lines, each line contains three integers i j cij, means we can build a channel from node Vi to node Vj, which cost cij. (1 ≤ i, j ≤ N; i ≠ j; 1 ≤ cij ≤ 100)
The source of water is always V1.
The input is terminated by N = M = 0.
Output
For each case, output a single line contains an integer represents the minimum cost.
If no design can irrigate all the farms, output "impossible" instead.
Sample Input
5 8 1 2 3 1 3 5 2 4 2 3 1 5 3 2 5 3 4 4 3 5 7 5 4 3 3 3 1 2 3 1 3 5 3 2 1 0 0
Sample Output
17 6
Problem setter: Hill
Source: TJU Contest August 2006
/* *********************************************** Author :CKboss Created Time :2015年07月04日 星期六 23时35分05秒 File Name :TJU2248.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int INF=0x3f3f3f3f; const int maxn=110; int n,m; struct Edge { int u,v,cost; }; Edge edge[maxn*maxn]; int pre[maxn],id[maxn],vis[maxn],in[maxn]; int zhuliu(int root,int n,int m,Edge edge[]) { int res=0,u,v; while(true) { for(int i=0;i<n;i++) in[i]=INF; for(int i=0;i<m;i++) { if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost; } } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF) return -1; int tn=0; memset(id,-1,sizeof(id)); memset(vis,-1,sizeof(vis)); in[root]=0; for(int i=0;i<n;i++) { res+=in[i]; v=i; while(vis[v]!=i&&id[v]==-1&&v!=root) { vis[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<m;) { 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++].cost-=in[v]; else swap(edge[i],edge[--m]); } n=tn; root=id[root]; } return res; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); u--; v--; edge[i].u=u; edge[i].v=v; edge[i].cost=w; } int ans=zhuliu(0,n,m,edge); if(ans==-1) puts("impossible"); else printf("%d\n",ans); } return 0; }