您的位置:首页 > 编程语言 > C语言/C++

hdu 4034 Graph(深化最短路floyd)

2015-11-24 20:55 591 查看
题目链接: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): 2188    Accepted Submission(s): 1101

[align=left]Problem Description[/align]
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?
 

[align=left]Input[/align]
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.

 

[align=left]Output[/align]
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.

 

[align=left]Sample Input[/align]

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

 

[align=left]Sample Output[/align]

Case 1: 6
Case 2: 4
Case 3: impossible

 

[align=left]Source[/align]
The 36th ACM/ICPC Asia Regional Chengdu
Site —— Online Contest
 

[align=left]Recommend[/align]
lcy   |   We have carefully selected several similar problems for you:  4039 4038 4036 4033 4037 

题目大意:给出一个地图,已知每两个点之间的最短路径,求原图最少有多少条边。
特别注意:
1、这个图是有向图。
2、可以找到原图就是输出最少有多少条边,否则输出-1。
3、用floyd找到最短路以及进行更新。
4、先得到边,再通过floyd去掉一些边,举个例子说:1->2的最短路为5,2->3的最短路为3,1->3的最短路为12,很明显1->2->3的<1->3的路径,所以1->3这条边可以去掉。
5、注意输出有个Case,避免wa。

详见代码。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

int Map[110][110],n;

int Search()
{
int flag=1;
int ans=0;
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
{
if (i==j)
continue;
for (int k=1; k<=n; k++)
{
if (i==k&&j==k)
continue;
if (Map[i][j]>Map[i][k]+Map[k][j]&&Map[i][k]&&Map[k][j])
{
flag=0;
return -1;
}
else
{
if (Map[i][j]==Map[i][k]+Map[k][j]&&Map[i][k]&&Map[k][j])
{
ans++;
break;
}
}
}
}
}
return ans;
}

int main()
{
int T;
int nn;
int Case=1;
scanf("%d",&T);
while (T--)
{
nn=0;
scanf("%d",&n);
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
{
scanf("%d",&Map[i][j]);
if (Map[i][j]!=0)
nn++;
}
}
printf ("Case %d: ",Case++);
int cmp=Search();
if (cmp==-1)
printf ("impossible\n");
else
printf ("%d\n",nn-cmp);
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 算法