http://acm.timus.ru/problem.aspx?space=1&num=1770
假设有可行解
根据所给最短路的情况进行分类 枚举两点最短路
假设最短路是dist(i,j) 相连情况为 k(i,j)(-1表示没有直接相连,0表示相连了值为0,1表示相连了值为1)
1, dist(i,j)>1||dist(j,i)>1 --> k(i,j)==k(j,i)==-1.
2, dist(i,j)==1&&dist(j,i)==1 -->k(i,j)==k(j,i)==-1.
3, dist(i,j)==0&&dist(j,i)==0 -->k(i,j) k(j,i) 可以都等于0
4, dist(i,j)==1&&dist(j,i)==0 -->k(i,j) 可以等于1, k(j,i) 可以等于0.
4, dist(i,j)==0&&dist(j,i)==1 -->k(i,j) 可以等于0,k(j,i)可以等于1.
然后根据 k() 的情况 进行 floyd 看是否可以得到 dist()
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<algorithm>
#include<cmath>
#define LL long long
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const double PI=acos(-1.0);
const int N=305;
int a[N][N],b[N][N];
int ans[N][N];
int main()
{
//freopen("data.in","r",stdin);
int n;
cin>>n;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
cin>>a[i][j];
for(int i=1;i<=n;++i)
{
ans[i][i]=-1;
for(int j=i+1;j<=n;++j)
{
if(a[i][j]>1||a[j][i]>1)
ans[i][j]=ans[j][i]=-1;
else if(a[i][j]==1&&a[j][i]==1)
ans[i][j]=ans[j][i]=-1;
else if(a[i][j]==0&&a[j][i]==0)
ans[i][j]=ans[j][i]=0;
else if(a[i][j]==0&&a[j][i]==1)
{ans[i][j]=0;ans[j][i]=1;}
else if(a[i][j]==1&&a[j][i]==0)
{ans[i][j]=1;ans[j][i]=0;}
}
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(i==j)
b[i][j]=0;
else
b[i][j]=ans[i][j];
for(int l=1;l<=n;++l)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(b[i][l]!=-1&&b[l][j]!=-1&&(b[i][j]==-1||b[i][j]>b[i][l]+b[l][j]))
b[i][j]=b[i][l]+b[l][j];
bool blag=true;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(a[i][j]!=b[i][j])
blag=false;
if(!blag)
cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
cout<<(ans[i][j]+1);
cout<<endl;
}
}
return 0;
}
浙公网安备 33010602011771号