nwerc2013 A-Absurdistan Roads (最小生成树(kruskal)+最短路(floyd))
2014-08-27 14:25
190 查看
Absurdistan Roads
Time Limit: 5678/3456MS (Java/Others) Memory Limit: 65432/65432KB (Java/Others)
Submit
Status
The people of Absurdistan discovered how to build roads only last year. After the discovery, every city decided to build their own road connecting
their city with another city. Each newly built road can be used in both directions.
Absurdistan is full of surprising coincidences. It took all N cities
precisely one year to build their roads. And even more surprisingly, in the end it was
possible to travel from every city to every other city using the newly built roads.
You bought a tourist guide which does not have a map of the country with the new roads. It only contains a huge table with the shortest distances
between all pairs of cities using the newly built roads. You would like to know between which pairs of cities there are roads and how long they are,
because you want to reconstruct the map of the N newly
built roads from the table of shortest distances.
You get a table of shortest distances between all pairs of cities in Absurdistan using the N roads
built last year. From this table, you must
reconstruct the road network of Absurdistan. There might be multiple road networks with N roads
with that same table of shortest distances,
but you are happy with any one of those networks.
Input
For each test case:A line containing an integer N (2≤N≤2000) --
the number of cities and roads.
N lines
with N numbers
each. The j-th
number of the i-th
line is the shortest distance from city i to
city j.
All distances between two
distinct cities will be positive and at most 1000000.
The distance from i to i will
always be 0 and
the distance from i to j will
be the same as the distance from j to i.
Output
For each test case:Print N lines
with three integers 'a b c'
denoting that there is a road between cities 1≤a≤N and 1≤b≤N of
length 1≤c≤1000000,
where a≠b.
If there are multiple solutions, you can print any one and you can print the roads in any order. At least one solution is
guaranteed to exist.
Print a blank line between every two test cases.
Sample input and output
Sample Input | Sample Output |
---|---|
4 0 1 2 1 1 0 2 1 2 2 0 1 1 1 1 0 4 0 1 1 1 1 0 2 2 1 2 0 2 1 2 2 0 3 0 4 1 4 0 3 1 3 0 | 2 1 1 4 1 1 4 2 1 4 3 1 2 1 1 3 1 1 4 1 1 2 1 1 3 1 1 2 1 4 3 2 3 |
Source
Northwestern European Regional Contest 2013题意:给你一个邻接矩阵代表最短路的情况,让你给出n条原始的边,使得这个最短路成立。
方法:要找的都是必要的边。先构造1棵最小生成树,这n-1条边是部分答案,然后是找最后一条边。用floyd求出任意两点间的距离,
找出未满足最短距离并且这两个点的最短距离最小的边,如果都已满足最短距离则随意添加一条重边即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
struct Edge
{
int u,v,len;
}edge[4000005];
int dist[2005],mp[2005][2005];
int father[2005];
int N,num;
int cmp(Edge a,Edge b)
{
return a.len<b.len;
}
void init(int n)
{
memset(mp,INF,sizeof(mp));
for (int i=1;i<=n;i++)
father[i]=i;
}
int find_father(int x)
{
if (x!=father[x])
father[x]=find_father(father[x]);
return father[x];
}
void Kruskal()
{
int i,j,sum=0;
init(N);
for (i=0;i<num;i++)
{
int fa=find_father(edge[i].u);
int fb=find_father(edge[i].v);
if (fa!=fb)
{
father[fa]=fb;
mp[ edge[i].u ][ edge[i].v ]=mp[ edge[i].v ][ edge[i].u ]=edge[i].len;
printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].len);
sum++;
if (sum>=N-1)
break;
}
}
}
void floyd()
{
int i,j,k;
for (k=1;k<=N;k++)
for (i=1;i<=N;i++)
for (j=1;j<=N;j++)
{
if (mp[i][k]==INF)
break;
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
int main()
{
int i,j,flag=0;
while (~scanf("%d",&N))
{
num=0;
int w;
if (flag)
printf("\n");
flag=1;
for (i=1;i<=N;i++)
for (j=1;j<=N;j++)
{
scanf("%d",&w);
if (i<=j)
continue;
edge[num].u=i;
edge[num].v=j;
edge[num++].len=w;
}
sort(edge,edge+num,cmp);
Kruskal();
floyd();
for (i=0;i<num;i++)
{
if (edge[i].len!=mp[ edge[i].u ][ edge[i].v ])
{
printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].len);
break;
}
}
if (i==num)
printf("%d %d %d\n",edge[0].u,edge[0].v,edge[0].len);
}
return 0;
}
/*
4 0 1 2 1 1 0 2 1 2 2 0 1 1 1 1 0 4 0 1 1 1 1 0 2 2 1 2 0 2 1 2 2 0 3 0 4 1 4 0 3 1 3 0
*/
相关文章推荐
- nwerc2013 A-Absurdistan Roads (最小生成树(kruskal)+最短路(floyd))
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 图(Graph)——最小生成树、最短路径、Kruskal、Dijkstra、Floyd
- CCF CSP认证 201703-4 地铁修建 Dijkstra最短路 或 Kruskal最小生成树
- C++实现矩阵图的遍历·最小生成树(prim,kruskal)·最短路径(Dijkstra,floyd)
- 最小生成树算法(Prime、Kruskal)和最短路径算法(Dijkstra、Floyd)
- BZOJ1016([JSOI2008]最小生成树计数)Kruskal+Matrix_Tree定理
- ZOJ - 1586 QS Network (最小生成树 Kruskal)
- 最小生成树(kruskal)Codeforces 472D
- Prim和Kruskal最小生成树
- [算法系列之二十七]Kruskal最小生成树算法
- 最小生成树&最短路基础算法总结
- 最小生成树 Kruskal 算法 和 Prim算法
- POJ 3723 Conscription(构造+最小生成树Kruskal)
- 最小生成树-并查集-Kruskal-zoj-2048-special judge
- 最小生成树-kruskal 模板
- HDU 4750 最小生成树 kruskal
- 最小生成树(kruskal)
- Jungle Roads 最小生成树(kruskal)
- 杭电 1863 畅通工程 【最小生成树&&Kruskal】