题意:给一个有向图,问要从0号点能到达所有点所需要经过路径的最小权值和是多少,然而,若两点强联通,则这两点互相到达不需要花费。保证0号点能到达所有点
tarjan缩点以后直接取每个点入边中花费最小的即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<cmath> 7 #include<ctime> 8 #define LL long long int 9 using namespace std; 10 const int maxn=50050,maxm=100010; 11 12 LL rd(){ 13 LL x=0;char c=getchar();int neg=1; 14 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 15 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 16 return x*neg; 17 } 18 19 struct Edge{ 20 int a,b,l,ne; 21 }eg[maxm]; 22 int egh[maxn],ect; 23 int N,M; 24 int dfn[maxn],low[maxn],bel[maxn],stk[maxn],tot,pct,sct; 25 bool instk[maxn]; 26 int mi[maxn]; 27 28 inline void adeg(int a,int b,int l){ 29 eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect++; 30 } 31 32 void tarjan(int x){ 33 dfn[x]=low[x]=++tot; 34 stk[++sct]=x;instk[x]=1; 35 for(int i=egh[x];i!=-1;i=eg[i].ne){ 36 int j=eg[i].b; 37 if(instk[j]) low[x]=min(low[x],dfn[j]); 38 else if(!dfn[j]){ 39 tarjan(j);low[x]=min(low[x],low[j]); 40 } 41 } 42 if(low[x]==dfn[x]){ 43 ++pct; 44 while(sct){ 45 instk[stk[sct]]=0; 46 bel[stk[sct]]=pct; 47 if(stk[sct--]==x) break; 48 } 49 } 50 } 51 52 int main(){ 53 int i,j,k; 54 while(~scanf("%d%d",&N,&M)){ 55 memset(egh,-1,sizeof(egh)); 56 memset(dfn,0,sizeof(dfn)); 57 memset(instk,0,sizeof(instk)); 58 ect=tot=pct=sct=0; 59 for(i=1;i<=M;i++){ 60 int a=rd(),b=rd(),c=rd(); 61 adeg(a,b,c); 62 } 63 64 for(i=0;i<N;i++) if(!dfn[i]) tarjan(i); 65 memset(mi,127,sizeof(mi)); 66 for(i=0;i<ect;i++){ 67 if(bel[eg[i].a]==bel[eg[i].b]) continue; 68 mi[bel[eg[i].b]]=min(mi[bel[eg[i].b]],eg[i].l); 69 }int ans=0; 70 for(i=1;i<=pct;i++){ 71 if(i!=bel[0]) ans+=mi[i]; 72 }printf("%d ",ans); 73 } 74 }