A - Absurdistan Roads
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.
Task
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 6 = 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.
3Problem A: Absurdistan Roads
Example
input 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
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.
Task
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 6 = 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.
3Problem A: Absurdistan Roads
Example
input 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
给出图中任意两点最短路径的距离,要求构造一个n条边的图,符合这个结果。
先把所有的边按长度从小到大排序。然后从一个没有边的图开始,枚举每条边,依次考虑添加它们。如果图中两点的最短路径大于待考察的这条边,则这条边必须添加。这么做复杂度还是很高,因为每条边都还要再求一遍最短路。加了一个很重要的优化:当已经找到了n条边,或找到了n-1条边,且已经考察过10000条边时(此时已经找到答案的概率非常高,比较乱搞),就可以停止枚举了。
#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 2e3 + 5;
const int INF = 1e9;
const double eps = 1e-6;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> P;
#define fi first
#define se second
struct Edge{
int x, y, dis;
bool operator < (const Edge& e) const{
return dis < e.dis;
}
};
Edge edges[maxn*maxn];
int M[maxn][maxn];
vector<P> G[maxn];
int dis[maxn];
int bfs(int source, int sink){
priority_queue<P> q;
while(!q.empty())
q.pop();
for(int i = 0;i < maxn;i++)
dis[i] = INF;
q.push(P(0, source));
dis[source] = 0;
while(!q.empty()){
P p = q.top();
q.pop();
int pos = p.se;
int step = -p.fi;
if(pos == sink){
return step;
}
if(step > dis[pos])
continue;
dis[pos] = step;
for(int i = 0;i < G[pos].size();i++){
int to = G[pos][i].fi;
int der = G[pos][i].se;
if(der+step < dis[to]){
q.push(P(-(der+step), to));
}
}
}
return INF;
}
vector<int> ans;
int main(){
int kase = 0, n;
while(scanf("%d", &n) != EOF){
if(kase)
puts("");
kase++;
int cnt = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
scanf("%d", &M[i][j]);
}
}
for(int i = 1;i <= n;i++){
for(int j = i+1;j <= n;j++){
edges[cnt++] = (Edge){i, j, M[i][j]};
}
}
sort(edges, edges+cnt);
ans.clear();
for(int i = 1;i <= n;i++)
G[i].clear();
for(int i = 0;i < cnt;i++){
int x = edges[i].x;
int y = edges[i].y;
int dis = edges[i].dis;
if(bfs(x, y) > dis){
ans.push_back(i);
G[x].push_back(P(y, dis));
G[y].push_back(P(x, dis));
}
if(ans.size()==n || (ans.size()==n-1 && i > 10000))
break;
}
int Size = ans.size();
for(int i = 0;i < Size;i++){
printf("%d %d %d\n", edges[ans[i]].x, edges[ans[i]].y, edges[ans[i]].dis);
}
if(Size < n)
printf("%d %d %d\n", edges[ans[Size-1]].x, edges[ans[Size-1]].y, edges[ans[Size-1]].dis);
}
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
*/