题目链接
Kingdom
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 194 Accepted Submission(s): 106
Special Judge
Problem Description
Teacher Mai has a kingdom consisting of n cities. He has planned the transportation of the kingdom. Every pair of cities has exactly a one-way road.
He wants develop this kingdom from one city to one city.
Teacher Mai now is considering developing the city w. And he hopes that for every city u he has developed, there is a one-way road from u to w, or there are two one-way roads from u to v, and from v to w, where city v has been developed before.
He gives you the map of the kingdom. Hope you can give a proper order to develop this kingdom.
He wants develop this kingdom from one city to one city.
Teacher Mai now is considering developing the city w. And he hopes that for every city u he has developed, there is a one-way road from u to w, or there are two one-way roads from u to v, and from v to w, where city v has been developed before.
He gives you the map of the kingdom. Hope you can give a proper order to develop this kingdom.
Input
There are multiple test cases, terminated by a line "0".
For each test case, the first line contains an integer n (1<=n<=500).
The following are n lines, the i-th line contains a string consisting of n characters. If the j-th characters is 1, there is a one-way road from city i to city j.
Cities are labelled from 1.
For each test case, the first line contains an integer n (1<=n<=500).
The following are n lines, the i-th line contains a string consisting of n characters. If the j-th characters is 1, there is a one-way road from city i to city j.
Cities are labelled from 1.
Output
If there is no solution just output "-1". Otherwise output n integers representing the order to develop this kingdom.
Sample Input
3 011 001 000 0
Sample Output
1 2 3题意:n个城市,一对城市之间有且仅有一条单向边,现在一个城市一个城市的发展,每发展一个城市,必须保证前面发展过的城市到它不超过两条边,也就是说要么与它直接相连,要么与它通过一个点间接相连。让你输出发展城市的先后顺序,无解输出-1.题解:容易想出一种解法,每次都找一个到所有没发展过的点的距离不超过2的点发展,如果不能找到则无解。但是如果暴力求到一个点距离小于等于2的点很可能超时。这题还有更好的做法。首先,因为两点之间一定有一条单向边,所以问题一定是有解的。假设u到v的距离大于2,那么v到u一定有一条边,也就是说v到u的距离一定为1,任意两点之间其中一个一定可以做另一个的前驱,所以问题一定有解。然后,每次找一个点到所有剩下的点的距离不超过2,这个点一定是所有点中出度最大的点。我们可以用反证法证明。假设u为出度最大的点,w1,w2,,wk与u直接相连,假设存在一个点v,使u到v的距离大于2,那么v一定有也与w1,w2,,,wk直接相连,并且v到u一定有条单向边,所以这与假设u为出度最大的点矛盾,所以出度最大的点,到所有点的距离不超过2。代码如下:#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<map> #define nn 510 #define inff 0x3fffffff typedef long long LL; using namespace std; int n; char tu[nn][nn]; bool vis[nn]; int a[nn]; int ans[nn]; int main() { int i,j,k; while(scanf("%d",&n)&&n) { for(i=0;i<n;i++) { scanf("%s",tu[i]); } memset(a,0,sizeof(a)); memset(vis,false,sizeof(vis)); for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(tu[i][j]=='1') a[i]++; } } int la=0; int mx,id; for(i=0;i<n;i++) { mx=-inff; for(j=0;j<n;j++) { if(!vis[j]&&a[j]>mx) { mx=a[j]; id=j; } } vis[id]=true; ans[la++]=id; for(k=0;k<n;k++) { if(tu[k][id]=='1') a[k]--; } } for(i=0;i<la;i++) { printf("%d%c",ans[i]+1,i==la-1?'\n':' '); } } return 0; }