zoukankan      html  css  js  c++  java
  • POJ 3114 Countries in War(强联通分量+Tarjan)

    题目链接

    题意 : n个城市,给出你m个关系,代表这城市x到城市y需要h小时,但如果两个城市是联通的,则耗时变为0,给你两个城市的编号,问你从前一个城市到后一个城市需要花费多长时间。

    思路 :我能说这个代码我直接将3592的代码一改就是这个了,那个求最长路,这个求最短路,把松弛那块儿改一下就行。反正先建图,将联通的点缩成一个联通分量,求的时候凡是一个联通分量时间就为0。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <string.h>
    
    using namespace std;
    
    const int maxn = 335555 ;
    const int INF = 1000000000 ;
    
    int belong[maxn],instack[maxn],dfn[maxn],low[maxn] ;
    int cntt,cnt,top,bcc_clock,cntb,n,m;
    int head1[maxn] ,head[maxn];
    int dis[maxn],coun[maxn] ;
    bool vis[maxn],flag[maxn] ;
    
    struct node
    {
        int u,v,w,next ;
    } p[maxn] ,ch[maxn];
    
    void addedge(int u,int v,int w)
    {
        p[cnt].u = u ;
        p[cnt].v = v ;
        p[cnt].w = w ;
        p[cnt].next = head[u] ;
        head[u] = cnt++ ;
    }
    
    void addnode(int u,int v,int w)
    {
        ch[cntt].u = u ;
        ch[cntt].v = v ;
        ch[cntt].w = w ;
        ch[cntt].next = head1[u] ;
        head1[u] = cntt++ ;
    }
    
    void tarjan(int u)
    {
        vis[u] = true ;
        dfn[u] = low[u] = ++bcc_clock ;
        instack[++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])
        {
            cntb++ ;
            int v ;
            do
            {
                v = instack[top--] ;
                vis[v] = false ;
                belong[v] = cntb ;
            }
            while(v != u) ;
        }
    }
    
    void Init()
    {
        memset(dfn,0,sizeof(dfn)) ;
        memset(low,0,sizeof(low)) ;
        memset(belong,0,sizeof(belong)) ;
        memset(vis,0,sizeof(vis)) ;
        memset(head,-1,sizeof(head)) ;
        memset(head1,-1,sizeof(head1)) ;
        cnt = 0,top = 0 ,cntb = 0,bcc_clock = 0,cntt = 0 ;
    }
    
    bool relax(int u,int v,int w)
    {
        if(dis[v] > dis[u] + w)
        {
            dis[v] = dis[u] + w ;
            return true ;
        }
        return false ;
    }
    
    bool spfa(int u)
    {
        memset(flag,false,sizeof(flag)) ;
        memset(coun,0,sizeof(coun)) ;
        flag[u] = true ;
        for(int i = 0 ; i <= n; i++)
            dis[i] = INF ;
        queue<int >Q ;
        Q.push(u) ;
        dis[u] = 0 ;
        while(!Q.empty ())
        {
            int st = Q.front() ;
            Q.pop() ;
            flag[st] = false ;
            for(int i = head1[st] ; i+1 ; i = ch[i].next)
            {
                if(relax(st,ch[i].v,ch[i].w) && !flag[ch[i].v])
                {
                    if((++coun[ch[i].v]) > n) return false ;
                    Q.push(ch[i].v) ;
                    flag[ch[i].v] = true ;
                }
            }
        }
        return true ;
    }
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            if(n == 0 && m == 0) break ;
            Init() ;
            int u,v,w ;
            for(int i = 0 ; i < m ; i++)
            {
                scanf("%d %d %d",&u,&v,&w) ;
                addedge(u,v,w) ;
            }
            for(int i = 1 ; i <= n ; i++)
            {
                if(!dfn[i])
                    tarjan(i) ;
            }
            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,p[j].w) ;
                    else addnode(i,v,0) ;
                }
            }
            int x ,O,D;
            scanf("%d",&x) ;
            for(int i = 0 ; i < x ; i++)
            {
                scanf("%d %d",&O,&D) ;
                spfa(O) ;
                if(dis[D] != INF)
                    printf("%d
    ",dis[D]) ;
                else
                    printf("Nao e possivel entregar a carta
    ") ;
            }
            printf("
    ") ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    网站名记录
    Unity 之 图片显示的真实大小
    Unity 之 Time
    数据库死锁分析与解决
    使用命令远程注销服务器
    Web自动化测试框架改进
    Tomcat 性能监控及调优
    移动互联网安全性测试技术简介
    白盒测试中如何实现真正意义上并发测试(Java)
    接口性能测试方案 白皮书 V1.0
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3554036.html
Copyright © 2011-2022 走看看