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("
");
        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
",i);
            else printf("Nao e possivel entregar a carta
");
        }
    }
    
}
原文地址:https://www.cnblogs.com/Ressed/p/9409510.html