Kawa Exam

题解:先scc把图变成树, 然后对于这若干棵树在进行dsu的操作。

dsu就是先找到最大的子树放在一边,然后先处理小的子树,最后处理大的子树。无限递归。

重要的一点就是 是否重新添加每个点的值,每次处理完小的子树之后会清空影响,然后处理完最大的子树之后就不再清空影响,这样减少复杂度。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 2e5 + ;
int head[N], to[N<<], nt[N<<], tot = ;
void add(int u, int v){
to[tot] = v;
nt[tot] = head[u];
head[u] = tot++;
}
int belong[N], dfn[N], low[N], now_time, scc_cnt;
int now = , st[N], ed[N];
vector<int> vc[N];
vector<pll> e[N];
stack<int> s;
void dfs(int u, int id){
dfn[u] = low[u] = ++now_time;
s.push(u);
for(int i = head[u]; ~i; i = nt[i]){
if(i == (id^)) continue;
if(!dfn[to[i]]) dfs(to[i], i);
if(!belong[to[i]]) low[u] = min(low[u], low[to[i]]);
}
if(dfn[u] == low[u]){
++scc_cnt;
int now;
while(){
now = s.top(); s.pop();
belong[now] = scc_cnt;
vc[scc_cnt].pb(now);
if(now == u) break;
}
}
}
void scc(int n){
for(int i = ; i <= scc_cnt; ++i) {
vc[i].clear();
e[i].clear();
st[i] = ed[i] = ; } now = ;
for(int i = ; i <= n; ++i) dfn[i] = low[i] = belong[i] = ;
while(!s.empty()) s.pop();
now_time = scc_cnt = ;
for(int i = ; i <= n; ++i)
if(!belong[i]) dfs(i,-);
for(int i = , u, v; i <= tot; i += ){
u = to[i], v = to[i+];
u = belong[u], v = belong[v];
if(u != v) e[u].pb(pll(v,i/+)), e[v].pb(pll(u,i/+));
}
}
int vis[N], col[N], col2[N], cnt[N], cnt2[N], mx1, mx2;
int sz[N], p[N];
int a[N];
void Add1(int u){
for(int i = , x; i < vc[u].size(); ++i){
x = vc[u][i];
cnt[col[a[x]]]--;
++col[a[x]];
cnt[col[a[x]]]++;
if(mx1 < col[a[x]]) mx1 = col[a[x]];
}
}
void Add2(int u){
for(int i = , x; i < vc[u].size(); ++i){
x = vc[u][i];
cnt2[col2[a[x]]]--;
++col2[a[x]];
cnt2[col2[a[x]]]++;
if(mx2 < col2[a[x]]) mx2 = col2[a[x]];
}
}
void Sub1(int u){
for(int i = , x; i < vc[u].size(); ++i){
x = vc[u][i];
--cnt[col[a[x]]];
--col[a[x]];
++cnt[col[a[x]]];
if(cnt[mx1] == ) --mx1;
}
}
void Sub2(int u){
for(int i = , x; i < vc[u].size(); ++i){
x = vc[u][i];
--cnt2[col2[a[x]]];
--col2[a[x]];
++cnt2[col2[a[x]]];
if(cnt2[mx2] == ) --mx2;
}
}
void ddfs(int o, int u){
//cout << o << ' ' << u << endl;
++now;
Add1(u);
p[now] = u;
st[u] = now;
sz[u] = vc[u].size();
for(int i = , v; i < e[u].size(); ++i){
v = e[u][i].fi;
if(v == o) continue;
ddfs(u, v);
sz[u] += sz[v];
}
ed[u] = now;
}
void Clear(int o, int u){
Sub1(u);
for(int i = ; i < e[u].size(); ++i){
int v = e[u][i].fi;
if(v == o) continue;
Clear(u, v);
}
}
int ttttmp;
int val[N];
void dsu(int o, int u, int op, int id){
int bigson = -, mx = -, iid;
for(int i = , v; i < e[u].size(); ++i){
v = e[u][i].fi;
if(v == o) continue;
if(mx < sz[v]) {
mx = sz[v];
bigson = v;
iid = e[u][i].se;
}
}
for(int i = , v; i < e[u].size(); ++i){
v = e[u][i].fi;
if(v == o || v == bigson) continue;
dsu(u, v, , e[u][i].se);
}
if(bigson != -)
dsu(u, bigson, , iid);
for(int i = , v; i < e[u].size(); ++i){
v = e[u][i].fi;
if(v != o && v != bigson) {
for(int i = st[v]; i <= ed[v]; i++){
Sub1(p[i]);
Add2(p[i]);
}
}
}
Sub1(u);
Add2(u);
val[id] = mx1+mx2-ttttmp;
if(op == ){
for(int i = st[u]; i <= ed[u]; i++){
Sub2(p[i]);
Add1(p[i]);
}
}
}
void init(){
memset(head, -, sizeof(head));
tot = ;
}
int main(){
int T, n, m;
scanf("%d", &T); while(T--){
init();
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) scanf("%d", &a[i]);
for(int i = , u, v; i <= m; ++i){
scanf("%d%d", &u, &v);
add(u,v); add(v,u);
}
scc(n);
int ans = ;
for(int i = ; i <= scc_cnt; ++i){
if(st[i]) continue;
mx1 = mx2 = ;
ddfs(,i);
ttttmp = mx1;
ans += mx1;
dsu(,i,,);
Clear(,i);
}
// cout << ans << endl;
for(int i = ; i <= m; i++){
printf("%d%c", ans+val[i]," \n"[i==m]);
val[i] = ;
}
}
return ;
}
/*
3
7 5
1 2 1 2 1 2 1
1 2
1 3
2 4
5 6
5 7
3 3
1 2 3
1 2
1 3
2 3
7 5
1 2 1 2 1 2 1
1 2
1 3
2 4
5 6
5 7
*/

zoj - 4059 Kawa Exam scc + dsu的更多相关文章

  1. 2018 ACM-ICPC青岛现场赛 B题 Kawa Exam 题解 ZOJ 4059

    题意:BaoBao正在进行在线考试(都是选择题),每个题都有唯一的一个正确答案,但是考试系统有m个bug(就是有m个限制),每个bug表示为第u个问题和第v个问题你必须选择相同的选项,题目问你,如果你 ...

  2. zoj 3721 Final Exam Arrangement【贪心】

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3721 来源:http://acm.hust.edu.cn/vjudg ...

  3. [置顶] 2013_CSUST暑假训练总结

    2013-7-19 shu 新生训练赛:母函数[转换成了背包做的] shuacm 题目:http://acm.hdu.edu.cn/diy/contest_show.php?cid=20083总结:h ...

  4. Final Exam Arrangement(ZOJ)

    In Zhejiang University, there are N different courses labeled from 1 to N. Each course has its own t ...

  5. ZOJ 3795 Grouping(scc+最长路)

    Grouping Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose there are N people in ZJU, whose ...

  6. zoj 3795 Grouping tarjan缩点 + DGA上的最长路

    Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practic ...

  7. ZOJ 3819 Average Score(平均分)

    Description 题目描述 Bob is a freshman in Marjar University. He is clever and diligent. However, he is n ...

  8. ZOJ 2819 Average Score 牡丹江现场赛A题 水题/签到题

    ZOJ 2819 Average Score Time Limit: 2 Sec  Memory Limit: 60 MB 题目连接 http://acm.zju.edu.cn/onlinejudge ...

  9. ZOJ 3687 The Review Plan I

    The Review Plan I Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on ZJU. Origi ...

随机推荐

  1. SCI论文的时态

    如果有的杂志对时态有要求,则以下所述都没有用了. 有些杂志也会专门有些比较“特别”的要求,比如Cell,要求Abstract全部使用一般现在时. 英语谓语动词时态共有16种,在英文科技论文中用得较为频 ...

  2. word 文档导出 (freemaker+jacob)--java开发

    工作中终于遇到了 需要导出word文旦的需求了.由于以前没有操作过,所以就先百度下了,基本上是:博客园,简书,CDSN,这几大机构的相关帖子比较多,然后花了2周时间 才初步弄懂.  学习顺序: 第一阶 ...

  3. 机器学习中的误差 Where does error come from?

    误差来自于偏差和方差(bias and variance)   对于随机变量 X,假设其期望和方差分别为 μ 和 σ2.随机采样 N 个随机变量构成样本,计算算术平均值 m,并不会直接得到 μ (除非 ...

  4. 「求助」关于MacOS 适配不了SOIL的问题 以及我自己愚蠢的解决办法

    我的环境 macOS High Sierra 10.13.6 (2018) 我的SOIL源是通过 终端 git clone https://github.com/DeVaukz/SOIL 直接从gay ...

  5. 『深度应用』NLP机器翻译深度学习实战课程·零(基础概念)

    0.前言 深度学习用的有一年多了,最近开始NLP自然处理方面的研发.刚好趁着这个机会写一系列NLP机器翻译深度学习实战课程. 本系列课程将从原理讲解与数据处理深入到如何动手实践与应用部署,将包括以下内 ...

  6. Mysql: 图解 inner join、left join、right join、full outer join、union、union all的区别

    转载来源 对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚. ...

  7. django在启动时抛出Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试 解决办法

    1.适用场景 在启动某个服务的时候,比如python中django启动的时候8000端口被占用,导致无法启动服务. 2.解决办法 通过命令行找出端口对应的PID进程 C:\Users\micha> ...

  8. 委托和lambda表达式,Action和Func

    1.为什么要用委托 我们为什么要有委托?任何东西存在即合理,不合理的也会被时间淘汰掉,委托既然存在肯定有存在的必要,我们来看一下什么时候可以用到委托. 接下来我们有个需求,就是调用一个方法,取出1-1 ...

  9. JAVA开发奇淫巧技(一)

    本章节持续收录常用且好用的IDE开发工具,基于myeclipse 1.Lombok是一种Java实用工具,可以帮助开发人员消除Java的冗长,具体看lombok的官网:http://projectlo ...

  10. 打印机服务配置篇WindowsServer2008

    本次配置Server2008 打印服务器    目的实现Kingdee远程打印服务,直接在金蝶客户端部署打印机服务器 服务器角色: --打印服务器 --LPD服务 --Internet打印 *打印服务 ...