问题 B: 反着来
时间限制: 1 Sec 内存限制: 32 MB
提交: 17 解决: 13
[提交] [状态] [命题人:外部导入]题目描述
相信大家都会解决有向图的最短路问题。这次我们反着来,给你一个有向图中每一对顶点之间的最短路的长度,请你计算出原图中最少可能包含多少条边。
输入
输入的第一行是一个整数T(T<=10),表示有T组测试数据。
每组输入的第一行是一个整数N(1<=N<=100),表示顶点个数。
接下来N行,每行输入N个整数,这些整数都小于10000。
第i行的第j个整数表示从顶点i到顶点j的最短路的长度。
第i行的第i个数字一定是0,其他的数字都大于0。输出
对于每组输入,先输出“Case k: ”,k表示样例的序号,从1开始。然后输出一个整数,表示原图中最少可能包含多少条边。如果原图不存在,则输出“impossible”(引号不输出)。
样例输入
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样例输出
Case 1: 6 Case 2: 4 Case 3: impossible
这个训练的时候就看了下题目,样本也没有画一下,更别说思考一秒了。直接放弃了没想到这个题用Flord就这么过了!!
实现代码:
#include<bits/stdc++.h>
using namespace std;//注意有向图
int main()
{
int i,j,k,n,m;
int t;
int sum;
int a[110][110];
cin>>t;
int p=1;
while(t--)
{
cin>>n;//顶点的个数
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>a[i][j];//单源的
}
}
int f=0;
sum=n*2;
//floyd
printf("Case %d: ",p++);
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i == j || i == k || k == j)//不能相同
continue;
if(a[i][j]!=-1&&a[i][k]!=-1&&a[k][j]!=-1)
{
if(a[i][j]>a[i][k]+a[k][j])
{
printf("impossible\n");
f=1;
break;
}
if(a[i][j]==a[i][k]+a[k][j])
{
a[i][j]=-1;
sum--;
}
}
}
if(f==1)
break;
}
if(f==1)
break;
}
if(f==0)
cout<<sum<<endl;//输出结果
}
return 0;
}
该博客讨论了一种逆向解决有向图最短路径问题的方法。给定每对顶点间的最短路径长度,任务是确定原图中至少需要多少条边。通过Floyd-Warshall算法检查路径的正确性,并在找到相等路径时减少边的数量。如果无法构造原图,则输出'Impossible'。提供的代码实现了这一逻辑并通过了样例测试。

1210

被折叠的 条评论
为什么被折叠?



