强连通。。
只需要最后记录每一个强连通分支的入度的最小值(其中有入度为0的,这样的不用考虑),把这些这些最小值加起来就是了。。
代码:
View Code
1 # include<stdio.h> 2 # define N 50005 3 # define M 100005 4 # define PI 0xfffffff 5 struct node{ 6 int from,to,next,data; 7 }edge1[M],edge2[M]; 8 int visit1[N],visit2[N], 9 head1[N],head2[N]; 10 int T[N],Belong[N],val[N],tol1,tol2,Bcnt,Tcnt; 11 void add(int a,int b,int c) 12 { 13 edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].data=c;edge1[tol1].next=head1[a];head1[a]=tol1++; 14 edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++; 15 } 16 void dfs1(int x) 17 { 18 int i; 19 visit1[x]=1; 20 for(i=head1[x];i!=-1;i=edge1[i].next) 21 if(visit1[edge1[i].to]==0) dfs1(edge1[i].to); 22 T[Tcnt++]=x; 23 } 24 void dfs2(int x) 25 { 26 int i; 27 Belong[x]=Bcnt; 28 visit2[x]=1; 29 for(i=head2[x];i!=-1;i=edge2[i].next) 30 if(visit2[edge2[i].to]==0) dfs2(edge2[i].to); 31 } 32 int main() 33 { 34 int i,n,m,a,b,x,y,sum,c; 35 while(scanf("%d%d",&n,&m)!=EOF) 36 { 37 for(i=0;i<=n;i++) 38 { 39 head1[i]=head2[i]=-1; 40 visit1[i]=visit2[i]=0; 41 } 42 tol1=tol2=0; 43 Bcnt=Tcnt=0; 44 while(m--) 45 { 46 scanf("%d%d%d",&a,&b,&c); 47 add(a,b,c); 48 } 49 for(i=0;i<n;i++) 50 if(visit1[i]==0) dfs1(i); 51 for(i=Tcnt-1;i>=0;i--) 52 { 53 if(visit2[T[i]]==0) 54 { 55 dfs2(T[i]); 56 Bcnt++; 57 } 58 } 59 for(i=0;i<Bcnt;i++) 60 val[i]=PI; 61 for(i=0;i<tol1;i++) 62 { 63 x=Belong[edge1[i].from]; 64 y=Belong[edge1[i].to]; 65 if(x!=y) 66 { 67 if(val[y]>edge1[i].data) val[y]=edge1[i].data; 68 } 69 } 70 sum=0; 71 for(i=0;i<Bcnt;i++) 72 if(val[i]!=PI) sum+=val[i]; 73 printf("%d\n",sum); 74 } 75 return 0; 76 }