【BAPC 2016】 C. Brexit BFS(拓扑排序)

A long time ago in a galaxy far, far away, there was a large interstellar trading union, consisting
of many countries from all across the galaxy. Recently, one of the countries decided to leave
the union. As a result, other countries are thinking about leaving too, as their participation
in the union is no longer beneficial when their main trading partners are gone. Picture by NASA
You are a concerned citizen of country X, and you want to find out whether your country will
remain in the union or not. You have crafted a list of all pairs of countries that are trading
partners of one another. If at least half of the trading partners of any given country Y leave
the union, country Y will soon follow. Given this information, you now intend to determine
whether your home country will leave the union.
Input
The input starts with one line containing four space separated integers C, P, X, and L. These
denote the total number of countries (2 ≤ C ≤ 200 000), the number of trading partnerships
(1 ≤ P ≤ 300 000), the number of your home country (1 ≤ X ≤ C) and finally the number
of the first country to leave, setting in motion a chain reaction with potentially disastrous
consequences (1 ≤ L ≤ C).
This is followed by P lines, each containing two space separated integers Ai and Bi satisfying
1 ≤ Ai < Bi ≤ C. Such a line denotes a trade partnership between countries Ai and Bi
. No
pair of countries is listed more than once.
Initially, every country has at least one trading partner in the union.
Output
For each test case, output one line containing either “leave” or “stay”, denoting whether
you home country leaves or stays in the union.
8 Problem C: Brexit
Sample Input 1 Sample Output 1
4 3 4 1 stay
2 3
2 4
1 2
Sample Input 2 Sample Output 2
5 5 1 1 leave
3 4
1 2
2 3
1 3
2 5
Sample Input 3 Sample Output 3
4 5 3 1 stay
1 2
1 3
2 3
2 4
3 4
Sample Input 4 Sample Output 4
10 14 1 10 leave
1 2
1 3
1 4
2 5
3 5
4 5
5 6
5 7
5 8
5 9
6 10
7 10
8 10
9 10

题意:每个人有若干个搭档,一开始整个团队只离开一个人,若一个人一半的搭档都走了,他也会走。现在问你某个人会不会离开

思路:

其实就类似拓扑排序,先消除第一个人连的边,然后看有无满足题意的,有的话进队,同样操作至队空或者碰到题给的那个编号。

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}

inline int read(){ int f = 1; int x = 0;char ch = getchar();while(ch>'9'|ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

const int V = maxn*2, E=maxn*4;
int n,m,id,s;
int head[E],pnt[E],nxt[E],e=1;
int vis[E];


void addedge(int u,int v)
{
    pnt[e]=v;       //当前以u为顶点,c为边长的,到v的一条边
   // cost[e]=c;      //存入当前边权值
    nxt[e]=head[u];     //下一个其实是前一个
    head[u]=e++;        //当前边编号
}
int in[E];
int pre[E];

inline void bfs()
{
    queue<int> q;
    q.push(s); in[s] = 0; vis[s] = 1;
    int flag = 0;
    while(!q.empty())
    {
        int cur = q.front(); q.pop();
        if( pre[cur] - in[cur] >= (pre[cur]+1)/2 && cur==id)
        {
            printf("leave\n");
            flag = 1;
            break;
        }
        for(int i = head[cur]; i ; i = nxt[i])
        {
            int v = pnt[i];    in[v] --;
            if(!vis[v]&&pre[v] - in[v] >= (pre[v]+1)/2 )
            {
                q.push(v);
                vis[v] = 1;
            }
        }
    }
    if(!flag)
    printf("stay\n");
}


int main()
{
    n = read(), m = read(), id = read(), s = read();
    rep(i,1,m)
    {
        int x = read(), y = read();
        addedge(x,y) , addedge(y,x);
        in[x]++, in[y]++;
        pre[x] = in[x], pre[y] = in[y];
    }
    bfs();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45492531/article/details/107541573