每个青蛙喝黑茶或者红茶或者都可以喝

M个矛盾关系 有矛盾的不能喝同种茶 但你可以花费Wi使得这个青蛙消除所有矛盾 把矛盾当作边 青蛙当作点 如果这两个青蛙只喝不同的一种茶就不建边

题目中保证了不存在奇环 可以黑白染色成二分图

然后把两个茶都可以喝的青蛙拆点 u表示该青蛙喝黑茶 u+n表示喝红茶 同时建边(u,u+n)

有四种情况:

1.两个青蛙都可以喝两种茶 建边(u,v) (u+n,v+n)

2.两个青蛙一个可以喝两种茶 一个可以喝黑茶 建边(u,v)

3.两个青蛙一个可以喝两种茶 一个可以喝红茶 建边(u,v+n)

4.两种青蛙都只能喝一种茶 建边(u,v)

然后黑白染色成二分图连S,T 跑二分图最小点权覆盖集

最后跑出来的答案要减去sumw 因为两种茶都可以喝的青蛙拆点导致每次拆点多花费了Wi

#include<bits/stdc++.h>
using namespace std;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << ], nxt[MAXM << ], f[MAXM << ], ed, S, T;
int n, m;
inline void addedge(int u, int v, int 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]);
}
}
}
memcpy(cur, Head, sizeof(Head));
return lev[T] != -;
}
inline int DFS(int u, int maxf) {
if (u == T || !maxf) {
return maxf;
}
int cnt = ;
for (int &i = cur[u], tem; 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;
}
int Dinic() {
int ans = ;
while (BFS()) {
ans += DFS(S, );
}
return ans;
}
void init(int SS, int TT) {
memset(Head, , sizeof(Head));
ed = ;
S = SS, T = TT;
return ;
}
struct node {
int kind;
int id;
int l, r;
int w;
} frog[];
vector<int> g[ * MAXN];
int color[ * MAXN];
int sumw;
void dfs(int x, int pre) {
for (int v : g[x]) {
if (v == pre || color[v] != -) {
continue;
}
color[v] = color[x] ^ ;
dfs(v, x);
}
}
inline void add(int u, int v) {
g[u].push_back(v);
g[v].push_back(u);
}
int main() {
int u, v;
while (scanf("%d %d", &n, &m) != -) {
sumw = ;
for (int i = ; i <= * n; i++) {
color[i] = -;
g[i].clear();
}
for (int i = ; i <= n; i++) {
scanf("%d", &frog[i].w);
}
for (int i = ; i <= n; i++) {
scanf("%d", &frog[i].kind);
if (frog[i].kind == ) {
sumw += frog[i].w;
add(i, i + n);
}
}
for (int i = ; i <= m; i++) {
scanf("%d %d", &u, &v);
if (frog[u].kind + frog[v].kind == ) {
continue;
}
if (frog[u].kind > frog[v].kind) {
swap(u, v);
}
if (frog[u].kind != ) {
if (frog[v].kind != ) {
add(u, v);
} else {
if (frog[u].kind == ) {
add(u, v);
} else {
add(u, v + n);
}
}
} else {
add(u, v);
add(u + n, v + n);
}
}
for (int i = ; i <= * n; i++) {
if (color[i] == -) {
color[i] = ;
dfs(i, -);
}
}
init(, * n + );
for (int i = ; i <= * n; i++) {
int wnow;
if (i > n) {
wnow = frog[i - n].w;
} else {
wnow = frog[i].w;
}
if (color[i] == ) {
addedge(S, i, wnow);
} else {
addedge(i, T, wnow);
}
}
for (int i = ; i <= * n; i++) {
if (color[i] == ) {
for (int v : g[i]) {
addedge(i, v, INF);
}
}
}
int anser = Dinic();
anser -= sumw;
printf("%d\n", anser);
}
return ;
}

SCU 4442 party 二分图最大点权独立集的更多相关文章

  1. SCU3185 Black and white(二分图最大点权独立集)

    题目大概说有几个黑色.白色矩阵,问能选出黑白不相交的矩形面积和的最大值. 建二分图,黑色矩阵为X部的点,白色为Y部,XY的点权都为其矩阵面积,如果有个黑白矩阵相交则它们之间有一条边,那样问题就是要从这 ...

  2. BZOJ 1475 方格取数(二分图最大点权独立集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1475 [题目大意] 给出一个n*n的方格,从中取一些不相邻的数字,使得和最大 [题解] ...

  3. zoj 3165 (最小割,最大点权独立集)

    胡伯涛的<最小割模型在信息学竞赛中的应用>写的真牛. 这道题是选择一些男孩和女孩参加party,邀请的男孩女孩之间不能有 8g,图就是个明显的二分图,就是选择一些点之间没有8g关系,就是二 ...

  4. 【最大点权独立集】【HDU1565】【方格取数】

    题目大意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 初看: 没想法 ...

  5. hdu 1565&&hdu 1569 (最大点权独立集)

    题目意思很明确就是选一些没有相连的数字,使和最大,建成二分图后求最大点权独立集,, #include<stdio.h> #include<string.h> const int ...

  6. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  7. 最小点权覆盖集&最大点权独立集

    最小点权覆盖集 二分图最小点权覆盖集解决的是这样一个问题: 在二分图中,对于每条边,两个端点至少选一个,求所选取的点最小权值和. 方法: 1.先对图二分染色,对于每条边两端点的颜色不同 2.然后建立源 ...

  8. HDU1569 最大流(最大点权独立集)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

随机推荐

  1. List的add方法与addAll方法的区别、StringBuffer的delete方法与deleteCharAt的区别

    List的add方法与addAll方法 区别 add add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素 addAll addAll是传 ...

  2. JUC AQS ReentrantLock源码分析

    警告⚠️:本文耗时很长,先做好心理准备,建议PC端浏览器浏览效果更佳. Java的内置锁一直都是备受争议的,在JDK1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6 ...

  3. C#操作Memcached帮助类

    在VS中安装Memcached,直接在NuGet下搜索Memcached,选择第一个进行安装: 服务端资源下载地址:https://pan.baidu.com/s/1gf3tupl 接下来开始写程序, ...

  4. Qt中mouseMoveEvent无效

    最近用Qt软件界面,需要用到mouseMoveEvent,研究了下,发现些问题,分享一下. 在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent,但是MouseMoveEvent为了不太耗资 ...

  5. mysql根据时间统计数据语句

    select FROM_UNIXTIME(`createtime`, '%Y年%m月%d日')as retm,count(*) as num  from `user` GROUP BY retm se ...

  6. 改变checkbox默认样式

    input[type='checkbox']{ width: 5rem; height: 5rem; -webkit-appearance: none; /*清除复选框默认样式*/ backgroun ...

  7. [转帖]密钥库文件格式(Keystore)和证书文件格式(Certificate)

    密钥库文件格式[keystore]代码 https://blog.csdn.net/zzhongcy/article/details/22755317 格式 : JKS 扩展名 : .jks/.ks ...

  8. oracle - for in loop 循环更新

    用法:目的更新B表的数据 查询出A表的字段,命名为表1.然后更新B表 BEGIN FOR 表1 IN ( SELECT [匹配字段],[更新字段] FROM A表 ) loop UPDATE B表 S ...

  9. XSSFWorkbook对象 进行zip打包时 用write资源流自动关闭处理办法

    XSSFWorkbook对象的write方法内会将传入的资源流自动关闭 导致下载excel失败 错误代码 OutputStream out = response.getOutputStream(); ...

  10. 监控提示message

    见文件 监控提示message.rar ---可作时时监控提示功能