您的位置:首页 > 产品设计 > UI/UE

UESTC-888-Absurdistan Roads(kruskal+floyd)

2016-01-31 09:00 429 查看
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 jto 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 InputSample 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

思路:先用kruskal求出n-1条边。那么n-1条边必然是满足的,接下来仅仅须要再找一条边就能够了,直接按权值从小到大枚举全部边直到找到一条边的距离与前面n-1条边构成的图里面该条边的距离不相等就可以,假设没找到就随便输出前n-1条边中的随意一条。

#include <stdio.h>
#include <algorithm>
#define INF 999999999
using namespace std;

struct E{
int u,v,val;
bool operator<(const E &p) const
{
return val<p.val;
}
}e[4000005];

int node[2005],dis[2005][2005];

int findroot(int x)
{
if(node[x]!=x) return node[x]=findroot(node[x]);

return node[x];
}

int main()
{
int n,i,j,k,t,u,v,val,cnt,roota,rootb;
bool first=1;

while(~scanf("%d",&n))
{
if(first) first=0;
else puts("");

cnt=0;

for(i=1;i<=n;i++) for(j=1;j<=n;j++)
{
scanf("%d",&val);

if(i<=j) continue;

e[cnt].u=i;
e[cnt].v=j;
e[cnt++].val=val;
}

sort(e,e+cnt);

for(i=1;i<=n;i++) node[i]=i;
for(i=1;i<=n;i++) for(j=1;j<=n;j++) dis[i][j]=INF;

t=0;

for(i=0;i<cnt;i++)
{
roota=findroot(e[i].u);
rootb=findroot(e[i].v);

if(roota!=rootb)
{
node[roota]=rootb;

dis[e[i].u][e[i].v]=dis[e[i].v][e[i].u]=e[i].val;

u=e[i].u,v=e[i].v,val=e[i].val;

printf("%d %d %d\n",e[i].u,e[i].v,e[i].val);

t++;

if(t>=n-1) break;
}
}

for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(dis[i][k]==INF) break;//没有这个优化直接T了。。。

dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}

for(i=0;i<cnt;i++)
{
if(e[i].val!=dis[e[i].u][e[i].v])
{
printf("%d %d %d\n",e[i].u,e[i].v,e[i].val);

break;
}
}

if(i==cnt) printf("%d %d %d\n",u,v,val);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: