Party

n frogs
are invited to a tea party. Frogs are conveniently numbered by 1,2,…,n.

The tea party has black and green tea in service. Each frog has its own preference. He or she may drink only black/green tea or accept both.

There are m pairs
of frogs who dislike each other. They fight when they are serving the same type of tea.

Luckily, frogs can be divided into 2 groups
such that no two frogs in the same group dislike each other.

Frogs like gems. If the i-th
frog can be paid wi gems
instead of serving tea, it will not fight with others anymore.

The party manager has to dicide how to serve tea/pay gems to avoid fights, minimizing the total gems paid.

Input

The input consists of multiple tests. For each test:

The first line contains 2 integers n,m (1≤n≤103,0≤m≤104).
The second line contains n integers w1,w2,…,wn.
(1≤wi≤106).

The third line contains n integers p1,p2,…,pn.
(1≤pi≤3). pi=1 means
the i-th
frog drinks only black tea. pi=2 means
it drinks only green one, while pi=3means
it accepts both.

Each of the following m lines
contains 2 integers ai,bi,
which denotes frog ai and bi dislike
each other. (1≤ai,bi≤n)

Output

For each test, write 1 integer
which denotes the minimum total gems paid.

Sample Input

    2 1
1 1
3 3
1 2
2 1
1 1
2 2
1 2
3 2
2 1 2
1 3 2
1 2
2 3

Sample Output

  0
1
1


省赛过了非常久以后我才来看这道题目。

然后,yy了几个晚上。最终发现果然是神一样的建图。

题目意思:有n个青蛙喝茶,有些青蛙仅仅能喝红茶,有些青蛙仅仅能喝绿茶,有些青蛙红茶绿茶都能够喝。

如今m对青蛙之间有矛盾。有矛盾的青蛙他们不能喝一样的茶,对于每一仅仅青蛙。能够给他w[i]金币。让他不喝茶。他就不会和不论什么青蛙矛盾了。最少须要给多少金币让他们之间没有矛盾存在。这题里面另一个非常重要的信息,我一開始没有看出来。

这句话————“Luckily,
frogs can be divided into 2 groups
such that no two frogs in the same group dislike each other.”事实上这句话非常关键,它的意思就是这个矛盾关系图不存在奇环,是一个2分图。

 有了这个条件。

我们如今考虑仅仅能喝一种茶的青蛙,红和绿之间即使存在矛盾也没有影响,那么仅仅用考虑红和红,绿和绿之间的矛盾关系。如果不考虑2种都能喝的青蛙。那么红和红,绿和绿都是单独的求出最大点权独立集。

因为是2分图,能够非常easy求。

如今考虑一仅仅2种茶都能够喝的青蛙。这里是关键,我的解法是把这个青蛙拆成2个点,一个点代表他喝红茶,一个点代表他喝绿茶,首先这2个点是不能同一时候存在。那么必定有边,然后如果这仅仅青蛙和其它仅仅喝红茶的青蛙有矛盾关系。那么相应就是这个青蛙喝红茶和那个青蛙喝红茶不能同一时候存在,其它情况事实上是类似的分析。这样拆点把矛盾关系图建立出来以后,实际上还是一个2分图。如今就是选出最大点权的点让这些点之间不存在矛盾关系。

实际上就是点权最大独立集。转换成求点权最小覆盖的模型,就能非常轻松的求解了。

。。。。想这么久,果然是神建图。事实上主要还是拆点。


VIEW CODE
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
const int mmax = 2010;
const int inf = 0x3fffffff; struct node
{
int flow;
int en;
int next;
}E[100*mmax];
int p[mmax];
int num;
void init()
{
memset(p,-1,sizeof p);
num=0;
}
void add(int st,int en,int flow)
{
E[num].en=en;
E[num].flow=flow;
E[num].next=p[st];
p[st]=num++;
E[num].en=st;
E[num].flow=0;
E[num].next=p[en];
p[en]=num++;
} int d[mmax];
int cur[mmax];
bool vis[mmax];
bool bfs(int st,int en)
{
memset(vis,0,sizeof vis);
d[st]=0;
vis[st]=1;
queue<int>q;
q.push(st);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=p[x]; i+1; i=E[i].next)
{
int v=E[i].en;
if(!vis[v]&&E[i].flow)
{
vis[v]=1;
d[v]=d[x]+1;
q.push(v);
}
}
}
return vis[en];
}
int dfs(int st,int en,int flow)
{
if(st==en||flow==0)
return flow;
int f=0,dd;
for(int &i=cur[st]; i+1;i=E[i].next)
{
int v=E[i].en;
if(d[st]+1==d[v]&&(dd=dfs(v,en,min(flow,E[i].flow)))>0)
{
E[i].flow-=dd;
E[i^1].flow+=dd;
flow-=dd;
f+=dd;
if(flow==0)
break;
}
}
return f;
}
int dinic(int st,int en,int n)
{
int flow=0;
while(bfs(st,en))
{
for(int i=0;i<=n;i++)
cur[i]=p[i];
flow+=dfs(st,en,inf);
}
return flow;
} vector<int>e[mmax];
int fg[mmax];
int w[mmax];
void dfs(int u)
{
int SZ=e[u].size();
for(int i=0;i<SZ;i++)
{
int v=e[u][i];
if(d[v]==-1)
{
d[v]=d[u]^1;
dfs(v);
}
}
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
for(int i=0;i<mmax;i++)
e[i].clear();
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&fg[i]);
if(fg[i]==3)
sum+=w[i];
}
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
init();
memset(d,-1,sizeof d);
for(int i=1;i<=n;i++)
{
if(d[i]==-1)
{
d[i]=0;
dfs(i);
}
}
int st=0,en=2*n+1;
for(int i=1;i<=n;i++)
{
if(d[i]==0)
{
if(fg[i]==1)
add(st,i,w[i]);
if(fg[i]==2)
add(i,en,w[i]);
if(fg[i]==3)
{
add(st,i,w[i]);
add(i,i+n,inf);
add(i+n,en,w[i]);
}
}
else
{
if(fg[i]==1)
add(i,en,w[i]);
if(fg[i]==2)
add(st,i,w[i]);
if(fg[i]==3)
{
add(i,en,w[i]);
add(st,i+n,w[i]);
add(i+n,i,inf);
}
}
} for(int u=1;u<=n;u++)
{
int Sz=e[u].size();
for(int i=0;i<Sz;i++)
{
int v=e[u][i];
if(d[u]==0 && d[v]==1)
{
if( (fg[u]==fg[v]) && (fg[u]!=3) )
{
if(fg[u]==1)
add(u,v,inf);
else
add(v,u,inf);
}
else if( (fg[u]==fg[v]) && (fg[u]==3) )
{
add(u,v,inf);
add(v+n,u+n,inf);
}
else if(fg[u]==3 || fg[v]==3 )
{
if(fg[u]==3)
{
if(fg[v]==1)
add(u,v,inf);
else
add(v,u+n,inf);
}
if(fg[v]==3)
{
if(fg[u]==1)
add(u,v,inf);
else
add(v+n,u,inf);
}
} }
}
}
printf("%d\n",dinic(st,en,en)-sum);
}
return 0;
}

scu oj 4442 Party(2015年四川省acm程序设计竞赛)的更多相关文章

  1. 华南师大 2017 年 ACM 程序设计竞赛新生初赛题解

    题解 被你们虐了千百遍的题目和 OJ 也很累的,也想要休息,所以你们别想了,行行好放过它们,我们来看题解吧... A. 诡异的计数法 Description cgy 太喜欢质数了以至于他计数也需要用质 ...

  2. SCU 4436 Easy Math 2015年四川省赛题

    题目链接:http://acm.scu.edu.cn/soj/problem/4436/ 题意:给你n个整数,求这n个数的平方根和是否是一个整数: 解题思路:如果这题每个数给他算出来,必然费时间,可能 ...

  3. 2010山东省第一届ACM程序设计竞赛

    休眠了2月了 要振作起来了!!... http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2155 因 ...

  4. UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)

    [题意]给定一个长度为N的数列,M个询问区间[L,R]内大于等于A小于等于B的数的个数. [题目链接]http://acm.upc.edu.cn/problem.php?id=2224 省赛的时候脑抽 ...

  5. 哈尔滨工业大学(威海)第九届ACM程序设计竞赛 Virtual Youtuber

    链接 [https://ac.nowcoder.com/acm/contest/624/G] 题意 其实题意说的辣鸡死了,没有说明确. y is the subsequences that its s ...

  6. 桂林电子科技大学第三届ACM程序设计竞赛 G 路径

    链接:https://ac.nowcoder.com/acm/contest/558/G来源:牛客网 小猫在研究树. 小猫在研究路径. 给定一棵N个点的树,每条边有边权,请你求出最长的一条路径,满足经 ...

  7. (java保留n位小数)precise math function 北京信息科技大学第十届ACM程序设计竞赛 第2题

    precise math function Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Othe ...

  8. 重复 桂林电子科技大学第三届ACM程序设计竞赛

    题目链接:https://ac.nowcoder.com/acm/contest/558/B import java.util.HashSet; import java.util.Scanner; p ...

  9. 相聚 桂林电子科技大学第三届ACM程序设计竞赛

    题目链接:https://ac.nowcoder.com/acm/contest/558/D 就是求有多少块区域,用DFS就可以解决,一遇到一个1就从其开始深搜,将其所在的区域块覆灭(变为0),再遇到 ...

随机推荐

  1. Flask框架 之模版

    一.过滤器 safe:禁用转义: <p>{{ '<em>hello</em>' | safe }}</p> capitalize:把变量值的首字母转成大 ...

  2. CAD嵌套打印(com接口版)

    当用户需要打印两个CAD控件的图纸时,可以采用嵌套打印实现.实现嵌套打印功能,首先将两个CAD控件放入网页中,C#代码如下: private void BatchPrintDialog() { MxD ...

  3. MySQL系列(一)--数据类型

    如何选择优化的数据类型: 1.通常更小的更好 相同级别的数据类型,选择占据空间更小的数据类型.更小的数据类型通常更快,因为占用更少的磁盘.内存和CPU缓存,处理时需要的 CPU周期也更少,但是要确保需 ...

  4. ubuntu 18.04 安装.net core

    要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系那就只好在琢磨了,然后就发现了在github有安装的方法因为是18.04 所以 wget -qO- https://packages.micro ...

  5. NET VBCSCompiler.exe占用100%,造成项目卡顿的的解决方法

    1)服务器环境 最低配 的window server 2008 r2, 配置低容易发现问题‘ 2)事件描述 :项目打开缓慢,查询列表卡顿 3)问题分析:排除代码问题, ->打开服务器任务管理器 ...

  6. 零基础入门学习Python(2)--用Python设计第一个游戏

    前言 小甲鱼的Python课程都是围绕着一个个小游戏,进行Python的讲解,由易入难. 小游戏流程图 Created with Raphaël 2.1.2Startprint('---------- ...

  7. flask 开发配置

    flask 开发配置 一:在虚拟机里面安装ubuntu系统.略 二: apt install python3-pip #安装pip, pip3 install --upgrade pip 三: pip ...

  8. 利用类装饰器自定制property实现延迟计算

    class LazyProperty: ''' hello,我是非数据描述符(没有定义__set__,不然是大哥数据描述符了--!) ''' def __init__(self, func): pri ...

  9. 集训第六周 数学概念与方法 J题 数论,质因数分解

    Description Tomorrow is contest day, Are you all ready? We have been training for 45 days, and all g ...

  10. [bzoj1078][SCOI2008][斜堆] (贪心)

    Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小.但斜堆不必是平衡的,每个结 ...