神奇的国家 | ||||||
| ||||||
Description | ||||||
有一个由n个城市组成的国家,国王要求,每两个城市之间只能由一条单向的路相连,这样有些城市之间就不能相互到达 (A和B可以相互到达是指,从A出发可以到达B,从B出发也可以到达A),而有些城市之间就可以。你作为一个商人,想 在几个可以相互到达的城市之间贸易,那么请你求出那些城市之间是可以相互到达的。 输入数据保证有且只有一个环,但是不一定构成一些相互到达的城市。
| ||||||
Input | ||||||
每组数据的第一行包括两个整数n和m(0≤m≤n≤2000),n表示有n个城市,并且这些城市之间有n条路相连,m表示唯 一的一个入度为0的点。接下来的n行每行有两个整数s和t,表示从城市s到城市t有一条有向的路。 每个城市最多只会有20个城市与之相连。 当n=m=0时,输入结束。
| ||||||
Output | ||||||
每组输出包含一个行,如果存在可以相互到达的城市,那么就输出“TwIStOy is so clever.”否则输出“TwIStOy is so nb.”。 | ||||||
Sample Input | ||||||
5 0 0 1 1 2 2 3 3 4 4 1 6 0 0 1 0 2 1 3 1 4 4 5 2 5 | ||||||
Sample Output | ||||||
TwIStOy is so clever. TwIStOy is so nb.
| ||||||
Hint | ||||||
解释一下度: 度:即和这个节点相连的边的数目。 入度:即指向这个节点的边的数目。出度:即由这个点出发的边的数目。 度 = 入度 + 出度(在有向图中) 判断是否有环存在即可。 对经过的点进行标记,如果在有该节点出发的路径上,找到了之前标记的点,则说明有环。 如果由该节点出发的所有路径都没有找到环,就把该节点的标记取消 | ||||||
Source | ||||||
新生练习赛(2013.11.24) | ||||||
Author | ||||||
TwIStOy |
让我们找两个点,a,b,a能到b,并且能从b到a。第一思路是floyd递推路径关系,如果i到j有路,j到k有路,那么i到k就有路,最后遍历所有边,如果map【i】【j】==1并且map【j】【i】==1表示达到目的,输出clever就行了。但是看到数据范围瞬间枪毙,2000^3,剪枝无果,TLE两发、、、然后就想用dfs找环吧,如果能从1找到2,2找到3,3找到1,那么就说明也会有满足条件出现,可惜WA,忘记几个重要的点:满足条件不一定要成环。然后最后加上一个output【】【】数组AC、
思路:
1、output【】【】二维数组保存图,如果从i到j能走的到,output【i】【j】=1。否则为0,用dfs的过程给他填补数据、
2、dfs所有点,能找到的点,一律入output【起点】【找到的点】、
3、两层for遍历,如果output【i】【j】==1&&output【j】【i】==1,输出clever、
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int >map[2005];//邻接表
int output[2005][2005];
int vis[2005];//dfs不想找到重复的点
int ok;
int n,m;
void dfs(int qidian,int now)//简洁dfs
{
vis[now]=1;
output[qidian][now]=1;
for(int i=0;i<map[now].size();i++)
{
int nex=map[now][i];
if(vis[nex]==0)
dfs(qidian,nex);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(output,0,sizeof(output));
for(int i=0;i<n;i++)
map[i].clear();
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
map[x].push_back(y);
}
for(int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
dfs(i,i);
}
ok=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(output[i][j]==1&&output[j][i]==1&&i!=j)
{
//printf("%d %d\n",i,j);
ok=1;
break;
}
}
if(ok==1)break;
}
if(ok==1)
{
printf("TwIStOy is so clever.\n");
}
else
{
printf("TwIStOy is so nb.\n");
}
}
}