poj 3114 Countries in War

来源:互联网 发布:win7 mac地址修改 编辑:程序博客网 时间:2024/06/05 23:40

http://poj.org/problem?id=3114

这道题和poj 3592 一样,先缩点再spfa求最短路

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#define maxn 300000using namespace std;const int inf=1<<30;int head[maxn],head1[maxn],dfn[maxn],low[maxn],belong[maxn],stack1[maxn],dis[maxn],cnt[maxn];int e,ee,bcc_clock,bcnt,top,N,E,x,y,h,k,o,d;bool vis[maxn],visi[maxn];struct node{    int u,v,w,next;}p[maxn];struct node1{    int u,v,w,next;}pp[maxn];void add(int u,int v,int w){    p[e].u=u;    p[e].v=v;    p[e].w=w;    p[e].next=head[u];    head[u]=e++;}void addnode(int u,int v,int w){    pp[ee].u=u;pp[ee].v=v;    pp[ee].w=w;    pp[ee].next=head1[u];    head1[u]=ee++;}void tarjan(int u){    vis[u]=true;    dfn[u]=low[u]=++bcc_clock;    stack1[++top]=u;    for(int i=head[u]; i!=-1; i=p[i].next)    {        int v=p[i].v;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(vis[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u])    {        bcnt++;        int j;        do        {            j=stack1[top--];            vis[j]=false;            belong[j]=bcnt;        }while(j!=u);    }}void deal(){   bcc_clock=0,bcnt=0,top=0;   memset(vis,false,sizeof(vis));   memset(belong,0,sizeof(belong));   memset(dfn,0,sizeof(dfn));   for(int i=1; i<=N; i++)   {       if(!dfn[i])       {           tarjan(i);       }   }}void inti(){    memset(head,-1,sizeof(head));    memset(head1,-1,sizeof(head1));    e=0,ee=0;}bool ralex(int u,int v,int w){    if(dis[v]>dis[u]+w)    {        dis[v]=dis[u]+w;        return true;    }    return false;}bool spfa(int src){    memset(visi,false,sizeof(visi));    memset(cnt,0,sizeof(cnt));    queue<int>q;    for(int i=0; i<=N; i++)    {        dis[i]=inf;    }    dis[src]=0;    visi[src]=true;    q.push(src);    while(!q.empty())    {        int u=q.front();q.pop();        visi[u]=false;        for(int i=head1[u]; i!=-1; i=pp[i].next)        {            if(ralex(u,pp[i].v,pp[i].w)&&!visi[pp[i].v])            {                if((++cnt[pp[i].v])>N) return false;                visi[pp[i].v]=true;                q.push(pp[i].v);            }        }    }    return true;}int main(){    while(scanf("%d%d",&N,&E)!=EOF)    {        inti();        if(N==0&&E==0) break;        for(int i=0; i<E; i++)        {            scanf("%d%d%d",&x,&y,&h);            add(x,y,h);        }        deal();        for(int i=1; i<=N; i++)        {            for(int j=head[i]; j!=-1; j=p[j].next)            {                int v=p[j].v;                if(belong[i]==belong[v]) addnode(i,v,0);                else if(belong[i]!=belong[v]) addnode(i,v,p[j].w);            }        }        scanf("%d",&k);        for(int i=0; i<k; i++)        {            scanf("%d%d",&o,&d);            spfa(o);            if(dis[d]!=inf)                printf("%d\n",dis[d]);            else                printf("Nao e possivel entregar a carta\n");        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击