hdu2874 Connections between cities

H - Connections between cities
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

HDU 2874
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


数据很大,可以使用lca求出u和v的祖先结点f,则有dis[u-v]=dis[u]+dis[v]-2*dis[f]。
基本的lca,主要是存储答案的时候有点小技巧。见代码:


第一篇是使用vector存图,但是超内存,一般不会出现这种情况,说明这题数据量很大,而且一般vector存图失败,前向星也不一定能行,可能是不能直接建图,但是抱着试试态度改了下发现可以过,第二篇转载自别处http://blog.csdn.net/ice_crazy/article/details/9097397,代码风格清晰。


#include 
#include 
#include 
#include 
#include 
using namespace std;
int n,m,c;
const int maxn=10005;
int p[maxn];
int dis[maxn];
int ans[1000005];
int ID[maxn];
struct node
{
    int to,len;
};
vector vi[maxn];
struct node1{
    int v,id;
    };
vector v1[maxn];
void make_set(int i)
{
 p[i]=i;
}

int find_set(int i)
{
 if(i!=p[i]) p[i]=find_set(p[i]);
 return p[i];
}

void union_set(int i,int j)
{
 i=find_set(i),j=find_set(j);
 p[j]=i;
}
//tarjan算法主体
void dfs(int u,int d,int Id)
{
 int i,v;
 make_set(u);
 dis[u]=d;
 ID[u]=Id;
 for(i=0;iif(p[v]==-1)
  {
   dfs(v,d+vi[u][i].len,Id);
   p[v]=u;
  }
 }

 for(i=0;iif(p[v]!=-1&&ID[u]==ID[v])
     {
         ans[v1[u][i].id]=dis[u]+dis[v]-2*dis[find_set(v)];
     }
 }
}
void init()
{
    memset(p,-1,sizeof(p));
    memset(dis,0,sizeof(dis));
    memset(ans,-1,sizeof(ans));
    memset(ID,0,sizeof(ID));
    for(int i=0;i<=n;i++)
        vi[i].clear();
        for(int i=0;i<=n;i++)
            v1[i].clear();
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&c)!=EOF)
    {
        init();
        for(int i=0;iint u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            vi[u].push_back(node{v,c});
            vi[v].push_back(node{u,c});
        }
        for(int i=0;iint u,v;
            scanf("%d%d",&u,&v);
            v1[u].push_back(node1{v,i});
            v1[v].push_back(node1{u,i});
        }
        for(int i=1;i<=n;i++)
        {
            if(p[i]==-1)
                dfs(i,0,i);
        }
        for(int i=0;iif(ans[i]!=-1)
            cout<else
                cout<<"Not connected"<
#include"iostream"
#include"cstdio"
#include"cstring"
using namespace std;
const int N=10005;
const int M=20005;
const int N_Q=2000005;

int n,m,q,dis[N],vis[N],father[N],ans[N_Q/2];

struct Edge
{
    int v,len,next;
} edge[M];
int tot,head[N];
void add(int a,int b,int c)
{
    edge[tot].v=b;
    edge[tot].len=c;
    edge[tot].next=head[a];
    head[a]=tot++;
    edge[tot].v=a;
    edge[tot].len=c;
    edge[tot].next=head[b];
    head[b]=tot++;
}

struct Ques
{
    int v,index,next;
} Q[N_Q];
int q_tot,q_head[N];
void add_ques(int a,int b,int index)
{
    Q[q_tot].v=b;
    Q[q_tot].index=index;
    Q[q_tot].next=q_head[a];
    q_head[a]=q_tot++;
    Q[q_tot].v=a;
    Q[q_tot].index=index;
    Q[q_tot].next=q_head[b];
    q_head[b]=q_tot++;
}
int find(int k)
{
    if(father[k]==k)    return k;
    father[k]=find(father[k]);
    return father[k];
}
void Tarjan_LCA(int k,int deep,int root)
{
    int j,v;
    father[k]=k;
    vis[k]=root;
    dis[k]=deep;
    for(j=head[k]; j!=-1; j=edge[j].next)
    {
        v=edge[j].v;
        if(vis[v]!=-1)  continue;
        Tarjan_LCA(v,deep+edge[j].len,root);
        father[v]=k;
    }
    for(j=q_head[k]; j!=-1; j=Q[j].next)
    {
        v=Q[j].v;
        if(vis[v]!=root)    continue;
        ans[Q[j].index]=dis[v]+dis[k]-2*dis[find(v)];
    }
}

int main()
{
    int i;
    int a,b,c;
    while(scanf("%d%d%d",&n,&m,&q)!=-1)
    {
        tot=q_tot=0;
        memset(head,-1,sizeof(head));
        memset(q_head,-1,sizeof(q_head));
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        for(i=0; i<q; i++)
        {
            scanf("%d%d",&a,&b);
            ans[i]=-1;
            add_ques(a,b,i);
        }

        memset(vis,-1,sizeof(vis));
        for(i=1; i<=n; i++)
            if(vis[i]==-1)
                Tarjan_LCA(i,0,i);
        for(i=0; i<q; i++)
        {
            if(ans[i]==-1)
                printf("Not connected\n");
            else
                printf("%d\n",ans[i]);
        }
    }
    return 0;
}

你可能感兴趣的:(acm,lca)