[Codeforces 1037E] Trip

[题目链接]

         http://codeforces.com/problemset/problem/1037/E

[算法]

        首先离线 , 将问题倒过来考虑 , 转化为 : 每次删除一条边 , 此时最多有多少人参加旅行

        假设所有点都选取 , 那么 ,如果一个点的度数 < k , 显然这个点不能选 , 我们需要删除它和所有与它相邻的边

        显然 , 所有的点和边最多只会被删去一次 , 故时间复杂度为O(N + M)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;

int n , m , k;
int deg[MAXN],res[MAXN],x[MAXN],y[MAXN],q[MAXN];
bool visited[MAXN],del[MAXN];
vector< int > a[MAXN],b[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
int main()
{
        
        read(n); read(m); read(k);
        for (int i = 1; i <= m; i++)
        {
                read(x[i]); read(y[i]);
                a[x[i]].push_back(y[i]);
                a[y[i]].push_back(x[i]);
                b[x[i]].push_back(i);
                b[y[i]].push_back(i);
                deg[x[i]]++; deg[y[i]]++;        
        }
        int l = 1 , r = 0 ,ans = n;
        for (int i = 1; i <= n; i++)
        {
                if (deg[i] < k)
                {
                        visited[i] = true;
                        q[++r] = i;
                        ans--;
                }
        }
        for (int i = m; i >= 1; i--)
        {
                while (l <= r)
                {
                        int u = q[l++];
                        for (unsigned j = 0; j < a[u].size(); j++)
                        {
                                if (!del[b[u][j]])
                                {
                                        deg[u]--;
                                        deg[a[u][j]]--;
                                        del[b[u][j]] = true;
                                        if (!visited[a[u][j]] && deg[a[u][j]] < k)
                                        {
                                                ans--;
                                                visited[a[u][j]] = true;
                                                q[++r] = a[u][j];
                                                
                                        }
                                }
                        }
                }
                res[i] = ans;
                if (!del[i])
                {
                        del[i] = true;
                        deg[x[i]]--;
                        deg[y[i]]--;
                        if (!visited[x[i]] && deg[x[i]] < k)
                        {
                                visited[x[i]] = true;
                                ans--;
                                q[++r] = x[i];
                        }
                        if (!visited[y[i]] && deg[y[i]] < k)
                        {
                                visited[y[i]] = true;
                                ans--;
                                q[++r] = y[i];
                        }
                }
        }
        for (int i = 1; i <= m; i++) printf("%d\n",res[i]);
        
        return 0;
    
}

 

posted @ 2018-10-02 16:12  evenbao  阅读(177)  评论(0编辑  收藏  举报