Graph(Floyd)

http://acm.hdu.edu.cn/showproblem.php?pid=4034

Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2058    Accepted Submission(s): 1030

Problem Description
Everyone knows how to calculate the shortest path in a directed graph. In fact, the opposite problem is also easy. Given the length of shortest path between each pair of vertexes, can you find the original graph?
 
Input
The first line is the test case number T (T ≤ 100).
First line of each case is an integer N (1 ≤ N ≤ 100), the number of vertexes.
Following N lines each contains N integers. All these integers are less than 1000000.
The jth integer of ith line is the shortest path from vertex i to j.
The ith element of ith line is always 0. Other elements are all positive.
 
Output
For each case, you should output “Case k: ” first, where k indicates the case number and counts from one. Then one integer, the minimum possible edge number in original graph. Output “impossible” if such graph doesn't exist.
 
Sample Input
3
3
0 1 1
1 0 1
1 1 0
3
0 1 3
4 0 2
7 3 0
3
0 1 4
1 0 2
4 2 0
 
Sample Output
Case 1: 6
Case 2: 4
Case 3: impossible
 

题意:给出由已知点求出的每个点间的最短路,问你原先的图中最少有几个点

题解:对已经给出的最短路再求一遍最短路用Floyd ,如果在求得过程中发现有dist[i][j]>dist[i][k]+dist[k][j]的情况就说明所给的不是最短的路图,及impossible

而在求解的过程中,当dist[i][j]==dist[i][k]+dist[k][j]的时候说明从i 到j 的长度,可以通过k点到达,故可以将直接相连的i,j去掉,及标记dist[i][j] = INF;

注意两点: 1,可以先将impossible的情况单独先算出来,以防后面对dist[i][j]  = INF ;

2, 当i==j||j==k||j==k 的时候要continue掉,因为这个为0的点会更新其他所有的点

下面是代码

 #include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 103
#define INF 0x1fffffff
int mp[N][N];
int dist[N][N];
int main()
{
int i , j , k ;
int n;
int t ;
cin>>t;
int c = ;
while(t--)
{
c++;
scanf("%d",&n);
for( i = ; i < n ;i++)
{
for( j = ; j < n ;j++)
{
scanf("%d",&mp[i][j]);
dist[i][j] = mp[i][j];
}
}
bool flag = true;
for(k = ;flag && k < n ; k++)
{
for(i = ;flag && i < n ; i++)
{
for( j = ; flag&& j < n ;j++)
{
if(dist[i][j]>dist[i][k]+dist[k][j])
flag = false;
}
}
}
int cnt = ;
if(flag)
{
for( k = ; k < n ;k++)
{
for(i = ; i < n ;i++)
{
for(j = ;j < n ;j++)
{
if(i==j||j==k||k==i) continue;
if(dist[i][j]==dist[i][k]+dist[k][j])
{
dist[i][j] = INF;
//printf("%d %d %d\n", k ,i , j);
cnt++;
}
}
}
}
}
if(flag) printf("Case %d: %d\n",c,n*(n-)-cnt);
else printf("Case %d: impossible\n",c); }
return ;
}
上一篇:MySQL - 常用命令及常用查询SQL


下一篇:Matlab-简单的车牌识别并分割(学习笔记)