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

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. HIVE配置mysql metastore

    HIVE配置mysql metastore    hive中除了保存真正的数据以外还要额外保存用来描述库.表.数据的数据,称为hive的元数据.这些元数据又存放在何处呢?    如果不修改配置hive ...

  2. layui layer.open弹出框获取不了 input框的值

    layer.open({ title:'添加管理员', type: 1, content: $('.add_html').html(), btn:['添加', '取消'], btnAlign:'c', ...

  3. 前端手势控制图片插件书写三(将transform变化应用在图片和canvas画布上)

    注意:transform的scale为负数时,图片会垂直翻转 一.在使用transform将计算得到的变化应用到图片上后,需要考虑到我们每次计算的都是touchmove中本次的差量.在第一次移动过后. ...

  4. sql语句 两表关联查询计算数量

    select sum(a1.`num`)   from `order_orderlistrow` as a1 INNER JOIN `order_orderlist` as a2 on a1.`ord ...

  5. vue中使用第三方插件animate.css实现动画效果

    vue中使用第三方插件animate.css实现动画效果1.首先先引入第三方类animated.css2.将你所需要动画的标签用包裹起来3.在transition元素中添加enter-active-c ...

  6. Web安全小结之前端

  7. NOIP2012 DAY1 T2 国王游戏

    题目描述 恰逢 H国国庆,国王邀请n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最前面 ...

  8. Thinkphp命令行快速生成模型类方法

    进去cmd,切换到项目根目录,也就是think文件所在目录,执行下面的指令可以生成index模块的blog模型类文件: >php think make:model index/Blog 生成的模 ...

  9. spark异常篇-OutOfMemory:GC overhead limit exceeded

    执行如下代码时报错 # encoding:utf-8 from pyspark import SparkConf, SparkContext from pyspark.sql import Spark ...

  10. S03_CH01_AXI_DMA_LOOP 环路测试

    S03_CH01_AXI_DMA_LOOP 环路测试 1.1概述 本课程是本季课程里面最简单,也是后面DMA课程的基础,读者务必认真先阅读和学习. 本课程的设计原理分析. 本课程是设计一个最基本的DM ...