Connections between cities
来源:互联网 发布:软件开发部门职责 编辑:程序博客网 时间:2024/06/05 04:07
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.
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 21 3 22 4 35 2 31 44 5
Sample Output
Not connected6HintHintHuge input, scanf recommended.
题解:典型的LCA离线算法,不过可能有多颗树,需要注意遍历每一颗树,但是又只遍历一次。所以需要用并查集判断询问的两个点是不是同一颗树上的点。
#pragma warning(disable:4996)#include <iostream>#include <cstring>#include <cstdio>#include <vector>using namespace std;struct Node{ int next;int dis;};vector<Node> vec[10001]; //保存邻接点与距离 int ans[10004]; //保存祖先,即并查集中的父节点,判断是不是同一个棵树上 int fa[10004]; // 保存祖先,dfs用 vector<int> q[10001]; //保存询问int p1[1000004]; //第几个询问的第一个城市,下标表示第几个询问 int p2[1000004]; //第二个城市,同上 bool visited[10004]; //访问标记 int d[10004]; //保存该点到根节点距离 int res[1000004]; //保存结果 int find(int x,int* f) //并查集 {if(x == f[x]){return x;}return f[x] = find(f[x],f);}void dfs(int x,int pre,int dis) //{fa[x] = x; //更新父节点 visited[x] = true; d[x] = dis; //保存该点到根的距离 int k;for(int i = 0;i < vec[x].size();i++){k = vec[x][i].next;if(!visited[k]) {dfs(k,x,dis + vec[x][i].dis);}}for(int i = 0;i < q[x].size();i++) //找出询问中与该点有关的 {k = (x == p1[q[x][i]] ? p2[q[x][i]] : p1[q[x][i]]);if(-1 == fa[k]) //表示另外一点访问过,那么最近祖先就是另外一点的祖先 {continue;}res[q[x][i]] = d[x] + d[k] - 2 * d[find(k,fa)]; //res保存第i个询问 }fa[x] = find(pre,fa); //更新该点的父节点 }int main(){int n,m,c;int u,v,dis;Node t1,t2;while(scanf("%d%d%d",&n,&m,&c) != EOF){for(int i = 1;i <= n;i++) //祖先指向自己 {ans[i] = i;}for(int i = 0;i < m;i++) //读取每一条边 {scanf("%d%d%d",&u,&v,&dis);t1.next = u;t1.dis = dis;t2.next = v;t2.dis = dis;vec[u].push_back(t2);vec[v].push_back(t1);int x = find(u,ans); //并查集,用来判断是不是同一棵树上的点 int y = find(v,ans);ans[x] = y;}for(int i = 1;i <= c;i++) //将每一个访问顺序放入q,dfs时直接通过p1,p2找到另外一个询问点 {scanf("%d%d",&p1[i],&p2[i]);q[p1[i]].push_back(i); q[p2[i]].push_back(i);}memset(fa,-1,sizeof(fa));memset(visited,false,sizeof(visited));memset(res,-1,sizeof(res));for(int i = 1;i <= n;i++) //遍历每一颗树 {if(!visited[i]) //如果没访问过说明该节点所在的树未被访问 {dfs(i,i,0);}}for(int i = 1;i <= c;i++) //输出结果 {if(find(p1[i],ans) != find(p2[i],ans)) //切记这里不能用ans[p1[i] == ans[p2[i], { //因为可能他们祖先一样但是由于没有更新导致不一样 printf("Not connected\n"); //我在这里错误浪费了几个小时,提交10次左右wa }else{printf("%d\n",res[i]);}}for(int i = 1;i <= n;i++) //很重要 {vec[i].clear();q[i].clear();}}return 0;}
0 0
- hdu2874 Connections between cities
- HDU Connections between cities
- HDU2874 Connections between cities
- Connections between cities
- Connections between cities
- hdu2874 Connections between cities
- Connections between cities
- Connections between cities HDU
- Connections between cities HDU
- HDOJ 2874 Connections between cities
- HDU 2874 Connections between cities
- hdu 2874 Connections between cities
- HDU 2874 Connections between cities
- hdu 2874 Connections between cities
- hdu 2874 Connections between cities
- HDU 2874 Connections between cities
- hdu2874 Connections between cities--LCA
- HDU 2874 Connections between cities
- opencv如何获取摄像头的数量
- 三十而立,从零开始学ios开发(十四):Navigation Controllers and Table Views(上) - minglz - 博客园
- 最简单的基于FFmpeg的移动端例子附件:IOS自带播放器
- Overflow
- 三十而立,从零开始学ios开发(十三):Table Views(下)Grouped and I
- Connections between cities
- IP高清模组将为行业带来新动力
- 黑马程序员----基础题----我的基础题
- 三十而立,从零开始学ios开发(十二):Table Views(中)UITableViewCell定制 - minglz - 博客园
- Visual Studio 2015 Enterprise Key
- 三十而立,从零开始学ios开发(十二):Table Views(上) - minglz - 博客
- POJ 1700贪心算法
- 三十而立,从零开始学ios开发(十一):Tab Bars和Pickers - minglz - 博客
- 三十而立,从零开始学ios开发(十):Multiview Applications(多个xib之前的切换) - minglz - 博客园