B - Cactusophobia

思路:

点双联通分量+最大流

用tarjan求出每个点双联通分量

对于大小大于1的点双联通分量,它就是个环,那么源点和这个环相连,

容量为环的大小减一,这个环和环上的颜色连边,容量为一;

对于大小为1的点双连通分量,它只有一条边,那么源点和这个分量连边,

分量和边上颜色连边,容量都为1

然后所有颜色和汇点连边,容量为1

最后跑一遍最大流就可以了

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head const int N = 1e4 + , M = 4e4 + ;
const int INF = 0x7f7f7f7f;
vector<pii> G[N];
vector<int> bcc[N*];
int color[N*];
int low[N], dfn[N], stk[N*], tot = , top = , cnt = ;
int level[M], iter[M];
struct edge {
int to, w, rev;
};
vector<edge>g[M];
void add_edge(int u, int v, int w) {
g[u].pb(edge{v, w, g[v].size()});
g[v].pb(edge{u, , g[u].size()-});
}
void bfs(int s) {
mem(level, -);
queue<int>q;
level[s] = ;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = ; i < g[u].size(); i++) {
edge e = g[u][i];
if(e.w > && level[e.to] < ) {
level[e.to] = level[u] + ;
q.push(e.to); }
}
}
}
int dfs(int u, int t, int f) {
if(u == t ) return f;
for (int &i = iter[u]; i < g[u].size(); i++) {
edge &e = g[u][i];
if(e.w > && level[u] < level[e.to]) {
int d = dfs(e.to, t, min(f, e.w));
if(d > ) {
e.w -= d;
g[e.to][e.rev].w +=d;
return d;
}
}
}
return ;
}
int max_flow(int s, int t) {
int flow = ;
while(true) {
bfs(s);
if(level[t] < ) return flow;
int f;
mem(iter, );
while ((f = dfs(s, t, INF)) > ) {
flow += f;
}
}
}
void tarjan(int u, int fa) {
low[u] = dfn[u] = ++tot;
for (pii p : G[u]) {
int v = p.fi;
if(v == fa) continue;
if(!dfn[v]) {
stk[++top] = p.se;
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]) {
cnt++;
while(stk[top] != p.se) bcc[cnt].pb(stk[top--]);
bcc[cnt].pb(stk[top--]);
}
}
else if(dfn[v] < dfn[u]) {
stk[++top] = p.se;
low[u] = min(low[u], dfn[v]);
}
}
}
int main() {
int n, m, u, v, c;
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) {
scanf("%d %d %d", &u, &v, &color[i]);
G[u].pb(pii{v, i});
G[v].pb(pii{u, i});
}
tarjan(, );
int s = , t = cnt+m+;
for (int i = ; i <= cnt; i++) {
if(bcc[i].size() == )add_edge(s, i, );
else add_edge(s, i, bcc[i].size()-);
}
for (int i = ; i <= cnt; i++) {
for (int j : bcc[i]) {
add_edge(i, cnt+color[j], );
}
}
for (int i = ; i <= m; i++) add_edge(cnt+i, t, );
printf("%d\n", max_flow(s, t));
return ;
}

2016 Russian Code Cup (RCC 16), Final Round B - Cactusophobia的更多相关文章

  1. 2017 Russian Code Cup (RCC 17), Final Round

    2017 Russian Code Cup (RCC 17), Final Round A Set Theory 思路:原题转换一下就是找一个b数组,使得b数组任意两个数的差值都和a数组任意两个数的差 ...

  2. 2017 Russian Code Cup (RCC 17), Elimination Round D - Acute Triangles

    D - Acute Triangles 思路: 极角排序+点积叉积 在一个三角形中,如果它是直角或者顿角三角形,那么直角和顿角只会出现一次 所以直角和顿角三角形的个数等于直角和顿角的个数 所以锐角三角 ...

  3. [Russian Code Cup 2017 - Finals [Unofficial Mirror]]简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. Div1难度+ACM赛制  和几个大佬组队逛了逛 A.给一个大小为n的集合ai(1<=ai<=1000000),要求你构造一个大小 ...

  4. CF Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)

    1. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort    暴力枚举,水 1.题意:n*m的数组, ...

  5. Yandex.Algorithm 2018, final round

    Yandex.Algorithm 2018, final round A Smart Vending B LIS vs. LDS C Eat And Walk D Search Engine E Gu ...

  6. Google Code Jam Africa 2010 Qualification Round Problem B. Reverse Words

    Google Code Jam Africa 2010 Qualification Round Problem B. Reverse Words https://code.google.com/cod ...

  7. Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)

    这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...

  8. 8VC Venture Cup 2016 - Final Round (Div. 2 Edition)

    暴力 A - Orchestra import java.io.*; import java.util.*; public class Main { public static void main(S ...

  9. 8VC Venture Cup 2016 - Final Round (Div. 1 Edition) E - Preorder Test 树形dp

    E - Preorder Test 思路:想到二分答案了之后就不难啦, 对于每个答案用树形dp取check, 如果二分的值是val, dp[ i ]表示 i 这棵子树答案不低于val的可以访问的 最多 ...

随机推荐

  1. vb中的除法

    “\”:在Integer类型中,如果商带小数,则直接舍去小数部分,只保留整数部分.“/”:在Integer类型中,如果商带小数,则把小数部分以0.5为界限,小数部分大于0.5,则返回的整数部分+1:如 ...

  2. [No000018A]改善C#程序的建议11-20

    建议11:区别对待 == 和Equals CLR中将“相等性”分为两类:1.值相等性:两个变量包含的数值相等.2.引用相等性:两个变量引用的是内存中的同一个对象. 但并不是所有的类型的比较都是按照其本 ...

  3. 我对于B-树索引的内部结构与索引类型所做的笔记

    图 3-1 B-树索引的内部结构 分支块和页块 B-树索引有两种类型的块: 用于查找的分支块和用于存储值的叶块.B-树索引的上层分支块包含指向下层索引块的索引数据.在图 3-1 中,根分支块包含条目 ...

  4. C#中的double类型数据向SQL sqerver 存储与读取问题

    1.存储 由于double类型在SQLsever中并没有对应数据,试过对应float.real类型,发现小数位都存在四舍五入的现象,目前我使用的是decimal类型,用此类型时个人觉得小数位数应该比自 ...

  5. python使用grpc调用rpc接口

    proto文件: syntax = "proto3"; package coupon; // //message UnsetUseC2URequest { // int64 bid ...

  6. python 判断两个ip是不是处于同一网段

    a_ip:10.10.15.100b_ip:10.10.15.101c_ip:10.10.10.100netmask:255.255.255.0 def numtobinary(num): binar ...

  7. proto 2 语法

    一.proto文件 PB的定义是通过proto文件进行定义的,一个标准的类型如下: message SearchRequest { required string query = 1; optiona ...

  8. 【Checkio Exercise】Three Point Circle

    计算三角形外接圆的函数: Three Point Circle If we want to build new silos, then we need to make more formal and ...

  9. mac系统maven spring mvc小试牛刀

    转: https://blog.csdn.net/Hitourlee/article/details/77930309和https://www.cnblogs.com/xiaowenbo/p/6980 ...

  10. redis解决高并发下脏读问题

    //解决并发情况下卡脏读的问题 protected function BingFa($mobile, $ent_id){ $obj = EnterpriseMembers::getNewMemberC ...