Time Limit:2s Memory Limit:64MByte
Submissions:213Solved:41
Eric, the famous terrorist, wants to destroy all the cities in Byteland. There are nn cities numbered from 11 to nn in Byteland. Also there are mm roads connecting the cities. One can go from city uiui to vivi (and vise versa) using the ii-th road.
Eric sends nn robots in the ss-th city. The ii-th robot will go to destroy the ii-th city. If the ii-th city is destroyed, all the roads directly connected with the ii-th city will also be destroyed. The robot will not use the destroyed roads. If the ii-th robot cannot reach the ii-th city, it will just return to the ss-city.
Eric wants to know which cities will be destroyed, if he sends the (i+1)(i+1)-th robot only after the ii-th city is destroyed or the ii-th robot returns to the ss-th city.
题目大意:
一共有N个机器人,编号为i的机器人的目的是去拆毁i号城市,按照顺序(1~n)去派出机器人,当城市i被拆毁的时候,对应和城市i相连的边也会被拆毁。
这个图是一个无向图,共有N个点,M条边。
问你能够拆毁的城市的编号(需求从小到大排序)
思路:
1、我们如果按照顺序去派出机器人,那么拆边的操作相对比较复杂,我们不妨将拆变成建。
采用一种逆序思维去搞这个题。
那么我们从n到1去枚举点,按照枚举出来的点开始建边,如果一个点能够建出来一条道路通向起点,那么对应这个点就能够被拆毁。
2、那么每一次对应枚举出来的当前点i,如果与i相连的点中,有编号大于i的才能够走,所以我们不妨将这样的边通过并查集进行建立。
那么对于一轮结束之后,有find(i)==find(起点)的点i,就是答案中的一员。
3、过程维护,注意输出格式即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
vector<int >mp[100500];
int ans[100500];
int f[100500];
int n,m,ss;
int find(int a)
{
int r=a;
while(f[r]!=r)
r=f[r];
int i=a;
int j;
while(i!=r)
{
j=f[i];
f[i]=r;
i=j;
}
return r;
}
int merge(int a,int b)
{
int A,B;
A=find(a);
B=find(b);
if(A!=B)
{
f[B]=A;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&ss);
for(int i=1;i<=n;i++)mp[i].clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
int ff=0;
for(int i=1;i<=n;i++)f[i]=i;
for(int i=n;i>=1;i--)
{
int x=find(i);
for(int j=0;j<mp[i].size();j++)
{
int v=mp[i][j];
if(v>i)
{
int y=find(v);
if(x!=y)
{
merge(x,y);
}
}
}
int y=find(ss);
if(x==y)
{
ans[i]=1;
}
else ans[i]=0;
}
for(int i=1;i<=n;i++)
{
if(ans[i]==1)
{
if(ff==0)printf("%d",i),ff=1;
else printf(" %d",i);
}
}
printf("\n");
}
}