bzoj1015

来源:互联网 发布:淘宝华硕官方旗舰店 编辑:程序博客网 时间:2024/06/05 01:19

辣鸡题。。

倒着加点  加一个点就加一个联通块

连一条边就减一个联通块



#include <cstdio>#include <cstring>using namespace std;int n,m,k;bool nuse[400010];int ans[400010];struct edge {int u,v,next;}e[400010];int head[400010];int cnt;int Ban[400010];int father[400010];int read_int () {char c = getchar();int re = 0;for(;c > '9' || c < '0'; c = getchar());for(;c >= '0' && c <= '9';c = getchar())re = re * 10 + c - '0';return re;}void adde (int u,int v) {e[++cnt].v = v;e[cnt].u = u;e[cnt].next = head[u];head[u] = cnt;e[++cnt].v = u;e[cnt].u = v;e[cnt].next = head[v];head[v] = cnt;}int find (int u) {if(father[u] == u)return u;return father[u] = find(father[u]);}int main () {memset(head,-1,sizeof head);n = read_int();m = read_int();for(int i = 1;i <= n;++i)father[i] = i;for(int i = 1;i <= m;++i)adde(read_int() + 1,read_int() + 1);k = read_int();ans[k] = n - k;;for(int i = 1;i <= k;++i) {Ban[i] = read_int() + 1;nuse[Ban[i]] = 1;}for(int i = 1;i <= 2 * m;++i) {if(nuse[e[i].u] || nuse[e[i].v] || find(e[i].u) == find(e[i].v) )continue;--ans[k];father[find(e[i].u)] = find(e[i].v);}for(int i = k - 1;i >= 0;--i) {ans[i] = ans[i + 1] + 1;nuse[Ban[i + 1]] = 0;for(int j = head[Ban[i + 1]];j != -1;j = e[j].next) {if(nuse[e[j].u] || nuse[e[j].v] || find(e[j].u) == find(e[j].v) )continue;--ans[i];father[find(e[j].u)] = find(e[j].v);}}for(int i = 0;i <= k;++i)printf("%d\n",ans[i]);}


0 0
原创粉丝点击