poj 3114 Countries in War

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

這道題和poj 3592 一樣,先縮點再spfa求最短路

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define maxn 300000
using 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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章