Kingdom
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 609 Accepted Submission(s): 275
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*n的矩阵 1 表示 i->j有一条单向路径,0表示没有路径,任意两点之间有且仅有一条有向边要求输出一种建造城市的顺序,使得之前已经建造的城市可以到达当前建造的城市,且至多经过两条边。首先我们可以证明,这种方案是肯定存在的, 因为在一个满足题意的图中,入度最大的点一定是其他点在两步之内可达的。那么这个点就最后输出。 上面的结论是为什么呢。。题解告诉我们用反证法证明, 若u结点是当前图中入度最大的结点,假设v点存在该路径v->a->b->u, 由于u是入度最大的结点,那么v 不可能连到u以及 b或者与u直接相连的点(不然v就可以两步到达u了), 由于两点间有一条有向边,v连布到他们,那么他们到v一定有边,既v的入度至少是 u+指向u的点,既v的入度大于u的,这里矛盾了。 所以我们可以知道,在任何一个符合题意的图中,都可以知道最后输出的点, 我们每找到一个点,就标记,把与该点相连的边删去。这样找完了倒序输出就i可以了。#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <vector> using namespace std; const int maxn=505; int in[maxn]; char str[maxn][maxn]; vector<int>ans; int main() { int n,num; while(scanf("%d",&n)!=-1) { if(n==0) break; ans.clear(); memset(in,0,sizeof(in)); for(int i=0;i<n;i++) { scanf("%s",str[i]); for(int j=0;j<n;j++) { if(str[i][j]=='1') { in[j]++; } } } for(int i=0;i<n;i++) { int temp=0,max_in=-1; for(int j=0;j<n;j++) { if(in[j]>max_in) { max_in=in[j]; temp=j; } } in[temp]=-1; for(int j=0;j<n;j++) { if(str[temp][j]=='1') { in[j]--; } } ans.push_back(temp+1); } int m=ans.size(); for(int i=m-1;i>=0;i--) { if(i==0) printf("%d\n",ans[i]); else printf("%d ",ans[i]); } } return 0; }