拓扑排序 --- hdu 4948 : Kingdom

Kingdom

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 142    Accepted Submission(s): 84
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.
 

 

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.
 

 

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
 

 

Source
 

 

Mean: 

 

 

给你一个有n个城市(结点)有向图,现在要发展这些城市,每两个城市之间有且只有一条单向边。
发展城市必须要满足一下条件:
当发展城市w的时候,其他已经发展的城市到w的距离必须小于等于2。
现在要你输出发展的顺序。

 

 

analyse:

 

 

题目说每两个点之间至少有一条边,所以说数据保证了给的图一定是竞赛图。
由此可知,不能构造的情况是不存在的,也就是说可不能输出-1。
我们只需要对这个图进行一个逆拓扑排序,然后输出就可。

 

 

Time complexity:O(n^2)

 

Source code:

//Memory   Time
// 1347K   0MS
// by : Snarl_jsb
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define MAX 1100
#define LL long long
using namespace std;
char Map[500][500];
int degree[500];
bool vis[500];
int ans[500];
int main ()
{
//    freopen("cin.txt","r",stdin);
//    freopen("cout.txt","w",stdout);
    int n,i,j,k,l;
    while(cin>>n,n)
    {
        getchar();
        for(i=0;i<n;++i)
        {
            gets(Map[i]);
            degree[i]=0;
            vis[i]=0;

        }
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(Map[i][j]=='1')
                    degree[j]++;
        int vmax,key,idx=-1;
        for(int i=0;i<n;i++)
        {
            vmax=-1,key=-1;
            for(int j=0;j<n;j++)
                if(!vis[j]&&degree[j]>vmax)
                    vmax=degree[j],key=j;
            vis[key]=1;
            ans[++idx]=key;
            for(int i=0;i<n;i++)
                if(Map[key][i]=='1')
                    degree[i]--;
        }
        for(i=n-1;i>=0;--i)
            if(i==n-1)
                printf("%d",ans[i]+1);
            else
                printf(" %d",ans[i]+1);
        puts("");
    }
    return 0;
}

  

没想到这题数据这么水,直接对入度从大到小排序,然后输出就可:

//Memory   Time
// 1347K   0MS
// by : Snarl_jsb
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define MAX 1100
#define LL long long
using namespace std;
char Map[500][500];
struct Node
{
    int degree;
    int index;
};
Node node[500];
bool cmp(Node a,Node b)
{
    return a.degree>b.degree;
}
int main ()
{
//    freopen("cin.txt","r",stdin);
//    freopen("cout.txt","w",stdout);
    int n,i,j,k,l;
    while(cin>>n,n)
    {
        getchar();
        for(i=0;i<n;++i)
        {
            gets(Map[i]);
            node[i].degree=0;
            node[i].index=i;

        }
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(Map[i][j]=='1')
                    node[j].degree++;
        sort(node,node+n,cmp);
        for(i=n-1;i>=0;--i)
            if(i==n-1)
                printf("%d",node[i].index+1);
            else
                printf(" %d",node[i].index+1);
        puts("");
    }
    return 0;
}

  

上一篇:暴力枚举 + 24点 --- hnu : Cracking the Safe


下一篇:自定义属性剖析