分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

P1197 【[JSOI2008]星球大战】

发布时间:2023-09-06 02:21责任编辑:蔡小小关键词:暂无标签

很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。

某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。

但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。

现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。

这道题也没做,又去洛谷上复制了一下大佬的代码%%%:

 ?1 ?#include <algorithm> ?2 #include <cmath> ?3 #include <cstdio> ?4 #include <cstdlib> ?5 #include <cstring> ?6 #include <ctime> ?7 #include <iostream> ?8 #include <map> ?9 #include <queue> 10 #include <set> 11 #include <stack> 12 #include <string> 13 #include <vector> 14 using namespace std; 15 #define go(i, j, n, k) for (int i = j; i <= n; i += k) 16 #define fo(i, j, n, k) for (int i = j; i >= n; i -= k) 17 #define rep(i, x) for (int i = h[x]; i; i = e[i].nxt) 18 #define mn 400400 19 #define inf 1 << 30 20 #define ll long long 21 #define ld long double 22 #define fi first 23 #define se second 24 #define root 1, n, 1 25 #define lson l, m, rt << 1 26 #define rson m + 1, r, rt << 1 | 1 27 #define bson l, r, rt 28 inline int read(){ 29 ????int f = 1, x = 0;char ch = getchar(); 30 ????while (ch > ‘9‘ || ch < ‘0‘){if (ch == ‘-‘)f = -f;ch = getchar();} 31 ????while (ch >= ‘0‘ && ch <= ‘9‘){x = x * 10 + ch - ‘0‘;ch = getchar();} 32 ????return x * f; 33 } 34 inline void write(int x){ 35 ????if (x < 0)putchar(‘-‘),x = -x; 36 ????if (x > 9)write(x / 10); 37 ????putchar(x % 10 + ‘0‘); 38 } 39 //This is AC head above... 40 int n, m, k, usd[mn], ans[mn]; 41 pair<int, int> ee[mn]; 42 bool not_alive[mn]; 43 struct edge{ 44 ????int v,nxt/*,w*/; 45 } e[mn<<1]; 46 int h[mn],p; 47 inline void add(int a,int b/*,int c*/){ 48 ????p++; 49 ????e[p].nxt=h[a]; 50 ????h[a]=p; 51 ????e[p].v=b; 52 ????//e[p].w=c; 53 } 54 //链式前向星存图 55 int father[mn]; 56 inline int findx(int x){ 57 ????return father[x] == x ? x : father[x] = findx(father[x]); 58 } 59 inline void mergex(int x,int y){ 60 ????int xx = findx(x); 61 ????int yy = findx(y); 62 ????if (xx == yy) 63 ????????return; 64 ????srand((unsigned)time(NULL));//随机合并防止毒瘤出题人故意卡深度(自己都不知道会怎么并) 65 ????if(rand()%2){ 66 ????????father[xx] = yy; 67 ????}else{ 68 ????????father[yy] = xx; 69 ????} 70 } 71 //并查集 72 int main(){ 73 ????n = read(); 74 ????go(i,1,n,1){ 75 ????????father[i] = i; 76 ????} 77 ????m = read(); 78 ????go(i,1,m,1){ 79 ????????ee[i].first = read();//离线判断用 80 ????????ee[i].second = read(); 81 ????????add(ee[i].first, ee[i].second);//存图 82 ????????add(ee[i].second, ee[i].first); 83 ????} 84 ????k = read(); 85 ????memset(not_alive, false, sizeof(not_alive));//玄学初始化 86 ????fo(i,k,1,1){ 87 ????????usd[i] = read();//倒序记录被炸的顺序 88 ????????not_alive[usd[i]] = true;//记录哪个点 最后被炸掉了 89 ????} 90 ????int tot = n - k;//重点!这里记录目前剩的点数 91 ????go(i,1,m,1){//然后先把存活的点之间的边连上,放到一个集合里,总的连通块数-1 92 ????????if(!not_alive[ee[i].first] && !not_alive[ee[i].second] 93 ????????&& findx(ee[i].first) != findx(ee[i].second)){ 94 ????????????tot--; 95 ????????????mergex(ee[i].first, ee[i].second); 96 ????????} 97 ????} 98 ????ans[k + 1] = tot; 99 ????go(i,1,k,1){100 ????????tot++;101 ????????not_alive[usd[i]] = false;102 ????????for (int j = h[usd[i]]; j; j = e[j].nxt){//枚举与这个点连接的点,看会合并几次,合并几次就会减少几个连通块103 ????????????if(!not_alive[e[j].v] && findx(e[j].v) != findx(usd[i])){104 ????????????????tot--;105 ????????????????mergex(e[j].v, usd[i]);106 ????????????}107 ????????}108 ????????ans[k - i + 1] = tot;//倒序存储109 ????}110 ????go(i,1,k+1,1){//正序输出111 ????????cout << ans[i] << "\n";112 ????}113 ????return 0;114 }

P1197 【[JSOI2008]星球大战】

原文地址:https://www.cnblogs.com/zytwan/p/9931320.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved