hnu 12947 网址 http://acm.hnu.cn/online/?action=problem&type=show&id=12947
给出n 和 n*n的矩阵 a(i,j)表示i 到j 的距离 然后求n条边 是的这个最短路成立
用求最小生成树的方法求出n-1条边 这n-1条边肯定是有用的 主要是如何求出第n条边
用floyd求出任意两点之间的最短距离
然后找出不满足最短距离的边 把它输出 如果都满足那就随便输出啦
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#define eps 1e-8
#define op operator
#define MOD 10009
#define MAXN 100100
#define INF 0x3f3f3f3f
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOV(i,a,b) for(int i=a;i>=b;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define REV(i,a,b) for(int i=a-1;i>=b;i--)
#define MEM(a,x) memset(a,x,sizeof a)
#define ll __int64
using namespace std;
int n,cnt;
struct edge
{
int u,v;
int len;
bool operator <(const edge p)const
{
return len<p.len;
}
};
edge e[4000005];
int mp[2005][2005];
int parent[2010];
void init()
{
MEM(mp,INF);
for(int i=0;i<n;i++)
parent[i]=-1;
}
int Find(int x)
{
int s;
for(s=x;parent[s]>=0;s=parent[s]);
while(s!=x)
{
int tmp=parent[x];
parent[x]=s;
x=tmp;
}
return s;
}
void Union(int R1,int R2)
{
int r1=Find(R1),r2=Find(R2);
int tmp=parent[r1]+parent[r2];
if(parent[r1]>parent[r2])
{
parent[r1]=r2;
parent[r2]=tmp;
}
else
{
parent[r2]=r1;
parent[r1]=tmp;
}
}
void Kruskal()
{
int x,y;
init();
/* if(n==2)
{
printf("%d %d %d\n",e[0].u+1,e[0].v+1,e[0].len);
printf("%d %d %d\n",e[0].u+1,e[0].v+1,e[0].len);
return;
}*/
int num=0;
for(int i=0;i<cnt;i++)
{
x=e[i].u; y=e[i].v;
if(Find(x)!=Find(y))
{
num++;
printf("%d %d %d\n",e[i].u+1,e[i].v+1,e[i].len);
mp[e[i].u][e[i].v]=mp[e[i].v][e[i].u]=e[i].len;
Union(x,y);
}
if(num>=(n-1)) break;
}
// printf("%d %d %d\n",e[0].u+1,e[0].v+1,e[0].len);
}
void floyd()
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(mp[i][k]==INF) break;
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
int main()
{
//freopen("ceshi.txt","r",stdin);
int cs=0;
while(scanf("%d",&n)!=EOF)
{
cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
if(i>j)
{
e[cnt].u=i; e[cnt].v=j;
e[cnt].len=x;
cnt++;
}
}
}
sort(e,e+cnt);
if(cs>0)
puts("");
cs++;
Kruskal();
floyd();
int k;
for(k=0;k<cnt;k++)
{
if(mp[e[k].u][e[k].v]!=e[k].len)
{
printf("%d %d %d\n",e[k].u+1,e[k].v+1,e[k].len);
break;
}
}
if(k==cnt)
{
printf("%d %d %d\n",e[0].u+1,e[0].v+1,e[0].len);
}
}
return 0;
}