POJ Countries in War 3114

题目大意:

给定一些城市,然后再给一些寄信的路信,A,B,H代表把信从A城市寄到B城市需要H小时。

如果没有直接可以寄达的,可以先通过另外一个城市到达,比如A,B可以寄信,B,C可以寄信,那么,A,C也可以寄信。

其中两个城市之间如果可以相互寄信的话,那么这两个城市是属于一个国家的,寄信可以通过电子邮件,所以所需的时间为0.

题目中有K个询问,输入A,B询问A到B之间寄信最少需要多少时间

题目分析:

先求出强联通然后构图求最短路。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
usingnamespace std;
#define INF 0x7ffffff
#define maxn 510
typedef longlong LL;
#define Min(a,b) (a<b?a:b)
#define MOD 1000000007
int m, n, Time, top, ans;
int Stack[maxn], dfn[maxn], low[maxn], blocks[maxn];
bool InStack[maxn];
typedef struct node
{
    int e, w;
    node(int e=0,int w=0): e(e), w(w) {}
}node;
vector<vector<node> > G;
vector<vector<node> > G2;

void init()
{
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    ans = Time = top = 0;
    G.clear();
    G.resize(n+2);
    G2.clear();
    G2.resize(n+2);
}

void Spfa()
{
}

void Tarjan(int u)
{
    low[u] = dfn[u] = ++Time;
    Stack[top ++] = u;
    InStack[u] = true;
    int len = G[u].size();
    node v;
    for(int i=0; i<len; i++)
    {
        v = G[u][i];

        if( !low[v.e] )
        {
            Tarjan(v.e);
            low[u] = min(low[u], low[v.e]);
        }
        elseif(InStack[v.e])
            low[u] = min(low[u], dfn[v.e]);
    }
    int k;
    if(dfn[u] == low[u])
    {
        do
        {
            k = Stack[--top];
            InStack[k] = false;
            blocks[k] = ans;
        }while(u != k);
        ans ++;
    }
}
int Spfa(int Star,int End)
{
    int dist[maxn];
    bool vis[maxn];
    memset(vis, false, sizeof(vis));
    for(int i=0; i<ans; i++)
        dist[i] = INF;
    dist[Star] = 0;
    queue<node> Q;
    node P, Pn;
    Q.push(node( Star,0) );

    while( Q.size() )
    {
        P = Q.front();
        Q.pop();
        vis[P.e] = true;
        int len = G2[P.e].size();

        for(int i=0; i<len; i++)
        {
            Pn = G2[P.e][i];
            if(dist[Pn.e] > dist[P.e] + Pn.w)
            {
                dist[Pn.e] = dist[P.e] + Pn.w;
                if(!vis[Pn.e])
                    Q.push(Pn.e);
            }
        }
    }

   // for(int i=0; i<ans; i++)
     //   printf("----%d\n", dist[i]);return dist[End];
}

void solve()
{
    int k, a, b;
    for(int i=1; i<=n; i++)
    {
        if(!low[i])
            Tarjan(i);
    }

    for(int i=1; i <= n; i++)
    {
        int len = G[i].size();
        node v;
        for(int j=0; j<len; j++)
        {
            v = G[i][j];
            a = blocks[i], b = blocks[v.e];

            if(a != b)
            {
                G2[a].push_back(node(b,v.w) );
               // printf("%d->%d,%d\n",a, b, v.w);            }

        }
    }
    scanf("%d",&k);

    while(k --)
    {
        scanf("%d %d",&a, &b);
        a = blocks[a], b = blocks[b];
        int rel = Spfa(a,b);
        if(rel == INF)
            puts("Nao e possivel entregar a carta");
        else
            printf("%d\n", rel);
    }
    printf("\n");
}

int main()
{
    while(scanf("%d %d",&n, &m), m+n)
    {
        init();
        while(m--)
        {
            int a, b, c;
            scanf("%d %d %d",&a, &b, &c);
            G[a].push_back( node(b,c) );
        }
        solve();
    }
    return0;
}
时间: 2024-08-26 07:49:19

POJ Countries in War 3114的相关文章

POJ 3114 Countries in War 强连通+最短路

用floyd超时了...注定的事情...题意:看案例就跑出来了..不需要看题了把.. #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #include<vector> const int INF =1999299; int minn(int a,int b) { return a>b?b:a; } #define N 510 #define M

POJ 3114 Countries in War(强连通+最短路)

POJ 3114 Countries in War 题目链接 题意:给定一个有向图,强连通分支内传送不需要花费,其他有一定花费,每次询问两点的最小花费 思路:强连通缩点后求最短路即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <stack> #include <algorithm> using namespa

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

POJ3114 Countries in War【强连通分量】【最短路径】

题目链接: http://poj.org/problem?id=3114 题目大意: 间谍在战争期间想要传递一份谍报回国,谍报可以在邮局之间传递,但这种传递是单向的, 并且会小号一些时间.但是如果两个邮局在同一个国家的话,那么谍报在这两个邮局之间传 递是不消耗时间的,可以立即到达.如果几个邮局发出的谍报可以通过一些路径相互到达, 那么这些邮局就属于一个国家.那么问题来了:给出一个起点和终点,问最快什么时候能够 将谍报传递到. 思路: 本题求得是有向图上的最短路.以邮局为点,从一个邮局到达另一个邮

poj 1085 Triangle War (状压+记忆化搜索)

Triangle War Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2685   Accepted: 1061 Description Triangle War is a two-player game played on the following triangular grid: Two players, A and B, take turns filling in any dotted line connect

POJ 3114 Countries in War(强联通分量+Tarjan)

题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <vector> 5 #include <stack> 6 #include <queue> 7 #inc

POJ 3114 Countries in War(强连通分量+最短路)

题目大意: n个间谍 他们之间传送信息需要一定的时间一个联通分量里面的间谍属于一个国家,之间的信息传递不需要时间然后问你从一个间谍传一个信息到另一个间谍那需要最少时间 也可能传不到 思路:先缩点,再最短路,由于n最大只有500.可以用邻接矩阵,而且对缩点后的DAG的边权可以做贪心处理,只留两个强连通分量间的最短边长即可. //2852K 297MS C++ 2595B #include<cstdio> #include<iostream> #include<cstring&g

Countries in War (POJ 3114) Tarjan缩点+最短路

题目大意: 在一个有向图中,每两点间通信需要一定的时间,但同一个强连通分量里传递信息不用时间,给两点u,v求他们最小的通信时间. 解题过程: 1.首先把强连通分量缩点,然后遍历每一条边来更新两个强联通分量之间的距离.. 2.直接Floyd会超时,应该用dijstra或者spfa做k次最短路. 犯的错误:前向星数组开的太小,一直超时.

POJ3114 Countries in War (强连通分量 + 缩点 + 最短路径 + 好题)

题目链接 题意是说在几个邮局之间传送一份信件,如果出发点和终止点在同一个国家传递,则时间为0,否则让你求花费最少时间,如果不能传到,则输出Nao e possivel entregar a carta.判断邮局是否在同一个国家的依据是发出的信件可以相互到达. 如果直接求最短路则无法判断两个邮局是否在同一个国家,判断两个邮局是否属于同一个国家的标志是在这个国家邮局间可以相互到达,那么这就是强连通了,所以要先缩点判读邮局是否在同一个国家,如果不是,则重新建图,建图的时候要维护好边权,求出最短边权,在