1. 程式人生 > >HDU——2874 Connections between cities

HDU——2874 Connections between cities

cond 短路徑 find exist ava char instance lin 需要

          Connections between cities

          Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
            Total Submission(s): 11927 Accepted Submission(s): 2775


Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.

Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.

Input Input consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.

Output For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.

Sample Input 5 3 2 1 3 2 2 4 3 5 2 3 1 4 4 5

Sample Output Not connected 6
Hint Hint Huge input, scanf recommended.

Source 2009 Multi-University Training Contest 8 - Host by BJNU

Recommend gaojie | We have carefully selected several similar problems for you: 2873 2876 2872 2875 2877 題目重現:

第十次世界大戰以後,很多城市受到嚴重破壞,我們需要重建這些城市。 然而,所需的一些材料只能在某些地方生產。 所以我們需要將這些材料從城市運送到城市。 大多數道路在戰爭期間已經完全被摧毀,兩個城市之間可能沒有道路,也沒有圈子。
現在,你的任務來了。 在給你道路的條件之後,我們想知道是否存在任何兩個城市之間的路徑。 如果答案是肯定的,輸出它們之間的最短路徑。

思路:

看到這個題,是不是又激動半天,天哪,這不又是個模板嗎?!

不過,這個題比起以前的幾個題來要高級那麽一點點、、、這個題是森林,上幾個題是棵樹。

所以我們這個題進行處理的時候我們要判斷兩個點是否連通,也就是說他們是否在一棵樹裏。

我們用並查集處理就好了,剩下的就是lca的模板了、、、

代碼:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 21000
using namespace std;
bool vis[N];
int t,n,m,x,y,z,fx,fy,ans,tot;
int fa[N],dad[N],top[N],size[N],deep[N],head[N],dis[N];
int find(int x)
{
    if(x==dad[x]) return x;
    dad[x]=find(dad[x]);
    return dad[x];    
}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
struct Edge
{
    int to,dis,next,from;
}edge[N<<1];
int add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int begin()
{
    ans=0;tot=0;
    memset(fa,0,sizeof(fa));
    memset(top,0,sizeof(top));
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(edge,0,sizeof(edge));
    memset(deep,0,sizeof(deep));
    memset(size,0,sizeof(size));
    memset(head,0,sizeof(head));
}
int lca(int x,int y)
{
    for(;top[x]!=top[y];x=fa[top[x]])
     if(deep[top[x]]<deep[top[y]]) swap(x,y);
    if(deep[x]>deep[y]) swap(x,y);
    return x;
}
int dfs(int x)
{
    vis[x]=true;size[x]=1;
    deep[x]=deep[fa[x]]+1;
    for(int i=head[x];i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(fa[x]==to) continue;
        dis[to]=dis[x]+edge[i].dis;
        fa[to]=x;dfs(to);
        size[x]+=size[to];    
    }
}
int dfs1(int x)
{
    int t=0;
    if(!top[x]) top[x]=x;
    for(int i=head[x];i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(fa[x]!=to&&size[t]<size[to]) t=to;
    }
    if(t) top[t]=top[x],dfs1(t);
    for(int i=head[x];i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(fa[x]!=to&&to!=t) dfs1(to);
    }
}
int pd(int x,int y)
{
    if(find(x)==find(y)) return false;
    return true;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        m=read(),t=read();begin();
        for(int i=1;i<=n;i++) dad[i]=i;
        for(int i=1;i<=m;i++)
        {
            x=read(),y=read(),z=read();
            add(x,y,z),add(y,x,z);
            fx=find(x),fy=find(y);
            if(fx!=fy)  dad[fx]=fy;
        }
        for(int i=1;i<=n;i++)
          if(!vis[i]) dfs(i),dfs1(i);
        for(int i=1;i<=t;i++)
        {
            x=read(),y=read();
            if(pd(x,y)) printf("Not connected\n");
            else
            {
                ans=dis[x]+dis[y]-2*dis[lca(x,y)];
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

HDU——2874 Connections between cities