把每个点的点权当做是W[i]-V[i] 题目一眼是最大权闭合子图 但是可能会有重边自环和环 需要先搞成简单图 再tarjan缩点 缩点后就是裸的最大权闭合子图

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const ll INF = 200000000050000LL;
int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << ], nxt[MAXM << ], ed, S, T;
ll f[MAXM << ];
inline void addedge2(int u, int v) {
to[++ed] = v;
nxt[ed] = Head[u];
Head[u] = ed;
return;
}
inline void addedge(int u, int v, ll cap) {
to[++ed] = v;
nxt[ed] = Head[u];
Head[u] = ed;
f[ed] = cap;
to[++ed] = u;
nxt[ed] = Head[v];
Head[v] = ed;
f[ed] = ;
return;
}
inline bool BFS() {
int u;
memset(lev, -, sizeof(lev));
queue<int>q;
lev[S] = ;
q.push(S);
while (q.size()) {
u = q.front();
q.pop();
for (int i = Head[u]; i; i = nxt[i])
if (f[i] && lev[to[i]] == -) {
lev[to[i]] = lev[u] + ;
q.push(to[i]);
/*
if (to[i] == T)
{
return 1;
}
magic one way optimize
*/
}
}
memcpy(cur, Head, sizeof Head);
return lev[T] != -;
}
inline ll DFS(int u, ll maxf) {
if (u == T || !maxf) {
return maxf;
}
ll cnt = , tem;
for (int &i = cur[u]; i; i = nxt[i])
if (f[i] && lev[to[i]] == lev[u] + ) {
tem = DFS(to[i], min(maxf, f[i]));
maxf -= tem;
f[i] -= tem;
f[i ^ ] += tem;
cnt += tem;
if (!maxf) {
break;
}
}
if (!cnt) {
lev[u] = -;
}
return cnt;
}
ll Dinic() {
ll ans = ;
while (BFS()) {
ans += DFS(S, INF);
}
return ans;
}
void init(int SS, int TT) {
ed = ;
S = SS;
T = TT;
return;
}
//Directed tarjan(without repeat edge)
int deep, colorsum = ;
int top;/*sta目前的大小*/
int dfn[MAXN], color[MAXN], low[MAXN];
int sta[MAXN];//存着当前所有可能能构成强连通分量的点
bool visit[MAXN];//表示一个点目前是否在sta中
int cnt[MAXN];//各个强连通分量中含点的数目
ll valsum[MAXN];
void tarjan(int x) {
dfn[x] = ++deep;
low[x] = deep;
visit[x] = ;
sta[++top] = x;
for (int i = Head[x]; i; i = nxt[i]) {
int v = to[i];
if (!dfn[v]) {
tarjan(v);
low[x] = min(low[x], low[v]);
} else {
if (visit[v]) {
low[x] = min(low[x], low[v]);
}
}
}
if (dfn[x] == low[x]) {
color[x] = ++colorsum;
visit[x] = ;
while (sta[top] != x) {
color[sta[top]] = colorsum;
visit[sta[top--]] = ;
}
top--;
}
}
ll w[MAXN];
pair<int, int> Edge[MAXM];
map<pair<int, int>, int> mp;
int main() {
int n, m, x;
int u, v, c;
int TNT;
scanf("%d", &TNT);
while (TNT--) {
mp.clear();
scanf("%d %d", &n, &m);
top = colorsum = ;
for (int i = ; i <= n + ; i++) {
visit[i] = dfn[i] = low[i] = cnt[i] = color[i] = Head[i] = ;
valsum[i] = ;
}
ed = ;
for (int i = ; i <= n; i++) {
scanf("%lld", &w[i]);
}
for (int i = ; i <= n; i++) {
scanf("%d", &x);
w[i] -= x;
}
for (int i = ; i <= m; i++) {
scanf("%d %d", &u, &v);
if (u == v || mp[make_pair(u, v)]) {
Edge[i].first = u, Edge[i].second = u;
continue;
}
mp[make_pair(u, v)] = ;
Edge[i].first = u, Edge[i].second = v;
addedge2(u, v);
}
for (int i = ; i <= n; i++) {
if (!dfn[i]) {
tarjan(i);
}
}
for (int i = ; i <= n; i++) {
valsum[color[i]] += w[i];
}
init(, n + );
for (int i = ; i <= n + ; i++) {
Head[i] = ;
}
ll anser = ;
for (int i = ; i <= colorsum; i++) {
if (valsum[i] > ) {
anser += valsum[i];
addedge(S, i, valsum[i]);
} else if (valsum[i] < ) {
addedge(i, T, -valsum[i]);
}
}
for (int i = ; i <= m; i++) {
u = Edge[i].first;
v = Edge[i].second;
if (color[u] == color[v]) {
continue;
}
addedge(color[u], color[v], INF);
}
cout << anser - Dinic() << endl;
}
return ;
}

SCU 4584 tarjan+最大权闭合子图的更多相关文章

  1. bzoj 1565 [NOI2009]植物大战僵尸【tarjan+最大权闭合子图】

    一上来以为是裸的最大权闭合子图,上来就dinic -然后没过样例.不得不说样例还是非常良心的给了一个强连通分量,要不然就WA的生活不能自理了 然后注意到有一种特殊情况:每个植物向他保护的植物连边(包括 ...

  2. bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan

    bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...

  3. BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】

    题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...

  4. HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...

  5. BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)

    题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...

  6. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  7. HDU 3879 Base Station(最大权闭合子图)

    经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...

  8. [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...

  9. HDU5855 Less Time, More profit(最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5855 Description The city planners plan to build ...

随机推荐

  1. 【CSS】如何在一个页面中引入样式css

    CSS(Cascading Style Sheet)又叫层叠样式表.是我们学习前端必不可少的一门语言,学习它其实就是为了学会如何去更改页面标签的样式.目前使用最广的是css3,但同样的,他是从css2 ...

  2. 【无线安全实践入门】破解WiFi密码的多个方法

    本文希望可以帮助到想要学习接触此方面.或兴趣使然的你,让你有个大概的印象. 文中可能存在错误操作或错误理解,望大家不吝指正. !阅前须知! 本文是基于我几年前的一本笔记本,上面记录了我学习网络基础时的 ...

  3. 【机器学习】ICA算法简介

    ICA算法的研究可分为基于信息论准则的迭代估计方法和基于统计学的代数方法两大类,从原理上来说,它们都是利用了源信号的独立性和非高斯性.基于信息论的方法研究中,各国学者从最大熵.最小互信息.最大似然和负 ...

  4. python 删除文件或文件夹

    os.remove(path) 删除文件 path. 如果path是一个目录, 抛出 OSError错误.如果要删除目录,请使用rmdir(). remove() 同 unlink() 的功能是一样的 ...

  5. 2019JAVA课程总结

    课程总结 1.子类不能直接访问父类的私有属性,可通过get(),set()来间接访问. 2.super(),this()不可同时使用,因为其都必须放在首行,所以不可同时使用. 3.若删去super() ...

  6. Centos7 下安装docker

    Docker 运行在 CentOS 7 上,要求系统为64位.系统内核版本为 3.10 以上. Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位.系统内核 ...

  7. Postfix to Prefix Conversion & Prefix to Postfix Conversion

    Postfix to Prefix Conversion Postfix: An expression is called the postfix expression if the operator ...

  8. Ansj与hanlp分词工具对比

    一.Ansj 1.利用DicAnalysis可以自定义词库: 2.但是自定义词库存在局限性,导致有些情况无效: 比如:“不好用“的正常分词结果:“不好,用”. (1)当自定义词库”好用“时,词库无效, ...

  9. strCmd.Format("delete FROM userTable where name = '%s'", name);

    string.Format("select * from 数据库表 where 用户名='%s' and 密码='%s' ",m_1,m_2); 把[m_1]和[m_2]的值按照[ ...

  10. Python【无引号、单引号、双引号、三引号】

    无引号#数字和数学运算是标准化.有固定格式的>>> print(520) 520>>> print(1+1)2 单引号#文字却能够千变万化>>> ...