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

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. No manual entry for printf in section 3

    在引入标准库头文件的时候,很多时候要先查询一下该函数所属的库,以及基本用法,在linux系统下,可以使用 man 1-9 函数名称 但是 问题来了,No manual entry for printf ...

  2. 教你用免费的hihttps开源WEB应用防火墙阻止暴力破解密码

    教你用免费的hihttps开源WEB应用防火墙阻止暴力破解密码 很多企业都有自己的网站,需要用户登录后才能访问,但有大量的黑客攻击软件可以暴力破解网站密码,即使破解不了也非常恶心.有没有免费的解决办法 ...

  3. C语言控制台软件制作

    本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号:各行符号中心对齐:相邻两 ...

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

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

  5. MySQL主从同步报错1507

    mysql 从库上手动删除partiton后,主库未做修改.后期主库上删除partiton后,出现问题. 故障现场 Last_Errno: 1507 Last_Error: Error 'Error ...

  6. 正式发布! .NET开发控件集ComponentOne 新版本加入Blazor UI

    近期,由葡萄城推出的ComponentOne .NET开发控件集正式发布最新版本! ComponentOne 是一套专注于企业 .NET开发.支持 .NET Core 平台,并完美集成于 Visual ...

  7. [转]Mybatis之TypeHandler使用教程

    Mybatis之TypeHandler使用教程 https://blog.csdn.net/jokemqc/article/details/81326109 深入浅出Mybatis系列(五)---Ty ...

  8. vs code在打开新文件是覆盖上一个窗口的问题

    设置里面有个 enablePreview 去掉就好

  9. echarts 根据经纬度坐标在地图上描点

    var mapData = [ {'latitude':30.67, 'longitude':104.07}, {'latitude':34.76, 'longitude':113.65}, {'la ...

  10. linux安装字体库(simSun为例)

    在开发过程中,发现报表打印,字体和默认字体不一样.本地开发环境(windows)没问题,但是远程linux一直出现这样的问题.经过排查发现linux没有安装中文字体库宋体. linux查看当前的字体库 ...