Trips CodeForces - 1037E(思维dfs)

题意:

  就是几个人去旅游,组队的条件是对于某个队员 队里至少有两个是他的朋友,每天早晨都会有一对新人成为朋友

解析:

  用set标记互为朋友

  a【i】 b【i】 表示在第i天早晨 u和v成为朋友

  先求最后一天的  前几天的数量肯定小于最后一天的数量   然后从后向前每天互相消去互为朋友的a【i】 和 b【i】 然后再判断a【i】 和 b【i】 是否符合还符合情况

  把每个不符合的用vis标记 防止重复减

  

#include <bits/stdc++.h>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define pd(a) printf("%d\n", a);
#define plld(a) printf("%lld\n", a);
#define pc(a) printf("%c\n", a);
#define ps(a) printf("%s\n", a);
#define MOD 2018
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn = 1e6, INF = 0x7fffffff;
int n, m, k;
set<int> s[maxn];
int a[maxn], b[maxn], vis[maxn], res[maxn];
int ans;
void dfs(int u)
{
    if(s[u].size() >= k) return;
    if(vis[u]) return;
    vis[u] = 1;
    ans--;
    for(set<int>::iterator it=s[u].begin(); it!=s[u].end(); it++)
    {
        s[*it].erase(u);
        dfs(*it);
    }
    s[u].clear();
}

int main()
{
    int u, v;
    rd(n), rd(m), rd(k);
    ans = n;
    rep(i, 0, m)
    {
        rd(u), rd(v);
        s[u].insert(v), s[v].insert(u);
        a[i] = u, b[i] = v;
    }
    rap(i, 1, n)
    {
        dfs(i);
    }
    res[m-1] = ans;
    lep(i, 0, m-1)
    {
        s[a[i]].erase(b[i]);
        s[b[i]].erase(a[i]);
        dfs(a[i]);
        dfs(b[i]);
        res[i-1] = ans;
    }

    rep(i, 0, m)
        pd(res[i]);

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9580004.html