poj3114 Contries in War (tarjan+dijkstra)
缩完点后对每次询问做dijkstra即可
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<cmath> #include<ctime> #define pa pair<int,int> #define LL long long int using namespace std; const int maxn=550,maxm=250050; LL rd(){ LL x=0;char c=getchar();int neg=1; while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x*neg; } struct Edge{ int a,b,l,ne; }eg[maxm],eg2[maxm]; int egh[maxn],egh2[maxn],ect2,ect; int N,M,K; int dfn[maxn],low[maxn],bel[maxn],stk[maxn],tot,pct,sct; int mp[maxn][maxn],dis[maxn]; bool instk[maxn]; inline void adeg(int a,int b,int l){ eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect++; }inline void adeg2(int a,int b,int l){ eg2[ect2].a=a;eg2[ect2].b=b;eg2[ect2].l=l;eg2[ect2].ne=egh2[a];egh2[a]=ect2++; } void tarjan(int x){ dfn[x]=low[x]=++tot; stk[++sct]=x;;instk[x]=1; for(int i=egh[x];i!=-1;i=eg[i].ne){ int j=eg[i].b; if(instk[j]) low[x]=min(low[x],dfn[j]); else if(!dfn[j]){ tarjan(j); low[x]=min(low[x],low[j]); } }if(low[x]==dfn[x]){ ++pct; while(sct){ instk[stk[sct]]=0; bel[stk[sct]]=pct; if(stk[sct--]==x) break; } } } int dijkstra(int s,int e){ memset(dis,127,sizeof(dis)); priority_queue<pa,vector<pa>,greater<pa> > q; dis[s]=0;q.push(make_pair(0,s)); while(!q.empty()){ int p=q.top().second;q.pop(); if(p==e) return dis[e]; for(int i=egh2[p];i!=-1;i=eg2[i].ne){ int b=eg2[i].b; if(dis[b]>dis[p]+eg2[i].l){ dis[b]=dis[p]+eg2[i].l; q.push(make_pair(dis[b],b)); } } }return dis[e]; } int main(){ int i,j,k; while(1){ N=rd();if(!N) break;M=rd(); if(tot) printf("\n"); memset(egh,-1,sizeof(egh)); memset(egh2,-1,sizeof(egh2)); memset(dfn,0,sizeof(dfn)); memset(instk,0,sizeof(instk)); memset(mp,127,sizeof(mp)); ect=ect2=tot=pct=sct=0; for(i=1;i<=M;i++){ int a=rd(),b=rd(),c=rd(); adeg(a,b,c); }for(i=1;i<=N;i++) if(!dfn[i]) tarjan(i); for(i=0;i<ect;i++){ int a=bel[eg[i].a],b=bel[eg[i].b]; if(a==b) continue; mp[a][b]=min(mp[a][b],eg[i].l); } for(i=1;i<=pct;i++){ for(j=1;j<=pct;j++){ if(mp[i][j]<=123456) adeg2(i,j,mp[i][j]); } } for(K=rd();K;K--){ int a=rd(),b=rd(); i=dijkstra(bel[a],bel[b]); if(i<=1e8) printf("%d\n",i); else printf("Nao e possivel entregar a carta\n"); } } }