SCU 4442 Party
二分图的最小点权覆盖。
非常感谢巨巨@islands_的解答,还帮我画了一个图。
题目保证给出的边构成的图是一个二分图。
如果没有第三种类型的$frog$,那么问题就很简单了。即选择哪些点,覆盖住所有的边,并且要求选择的点的权值之和最小。可以转换成网络流来解决。
现在有第三种类型的$frog$,可以把这种$frog$拆成两个点,两点之间连边,然后其余和他有矛盾的点,分别向两个点中的一个点连边。画画图可以发现拆点之后的新图也是二分图。对这个图跑一次二分图的最小点权覆盖,如果拆点的边两端有一个点被选择,说明这个$frog$实际上是不选择的,如果拆点的边两端有两个点被选择,说明这个$frog$实际上被选择了,那么只要在结果上减去第三种类型的$frog$的权值和就可以了。
#include<bits/stdc++.h>
using namespace std; int n,m;
int w[],p[],dis[];
vector<int>g[]; const int maxn = + ;
const int INF = 0x7FFFFFFF;
struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int s, t; void init()
{
for (int i = ; i < maxn; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
int w = edges.size();
G[from].push_back(w - );
G[to].push_back(w - );
}
bool BFS()
{
memset(vis, , sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = ; i<G[x].size(); i++)
{
Edge e = edges[G[x][i]];
if (!vis[e.to] && e.cap>e.flow)
{
vis[e.to] = ;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a)
{
if (x == t || a == )
return a;
int flow = , f;
for (int &i = cur[x]; i<G[x].size(); i++)
{
Edge e = edges[G[x][i]];
if (d[x]+ == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
edges[G[x][i]].flow+=f;
edges[G[x][i] ^ ].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
if(!flow) d[x] = -;
return flow;
}
int dinic(int s, int t)
{
int flow = ;
while (BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
return flow;
} void B(int x)
{
queue<int>Q; Q.push(x); dis[x]=; while(!Q.empty())
{
x = Q.front(); Q.pop();
for(int i=;i<g[x].size();i++)
{
int to = g[x][i];
if(dis[to]!=-) continue;
dis[to] = dis[x]^;
Q.push(to);
}
}
} void ADD(int a,int b)
{
g[a].push_back(b);
g[b].push_back(a);
} int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=*n;i++) g[i].clear(); for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=n;i++)
{
scanf("%d",&p[i]);
if(p[i]==) ADD(i,i+n);
} for(int i=;i<=m;i++)
{
int A,B; scanf("%d%d",&A,&B);
if(p[A]+p[B]==) continue; if(p[A]==||p[A]==)
{
if(p[B]==||p[B]==) ADD(A,B);
else
{
if(p[A]==) ADD(A,B);
else ADD(A,B+n);
}
} else if(p[A]==)
{
if(p[B]==||p[B]==)
{
if(p[B]==) ADD(A,B);
else ADD(A+n,B);
}
else if(p[B]==)
{
ADD(A,B);
ADD(A+n,B+n);
}
}
} memset(dis,-,sizeof dis);
for(int i=;i<=*n;i++)
{
if(dis[i]!=-) continue;
B(i);
} init(); s=,t=*n+; for(int i=;i<=*n;i++)
{
if(dis[i]==) continue;
for(int j=;j<g[i].size();j++) AddEdge(i,g[i][j],INF);
} for(int i=;i<=*n;i++)
{
int V;
if(i<=n) V = w[i]; else V=w[i-n];
if(dis[i]==) AddEdge(s,i,V);
else AddEdge(i,t,V);
} int ans = dinic(s,t);
for(int i=;i<=n;i++) if(p[i]==) ans=ans-w[i]; printf("%d\n",ans); }
return ;
}
SCU 4442 Party的更多相关文章
- SCU 4442 party 二分图最大点权独立集
每个青蛙喝黑茶或者红茶或者都可以喝 M个矛盾关系 有矛盾的不能喝同种茶 但你可以花费Wi使得这个青蛙消除所有矛盾 把矛盾当作边 青蛙当作点 如果这两个青蛙只喝不同的一种茶就不建边 题目中保证了不存在奇 ...
- scu oj 4442 Party(2015年四川省acm程序设计竞赛)
Party n frogs are invited to a tea party. Frogs are conveniently numbered by 1,2,-,n. The tea party ...
- ACM:SCU 4437 Carries - 水题
SCU 4437 Carries Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practice ...
- ACM: SCU 4438 Censor - KMP
SCU 4438 Censor Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practice D ...
- ACM: SCU 4440 Rectangle - 暴力
SCU 4440 Rectangle Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practic ...
- SCU 4424(求子集排列数)
A - A Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice ...
- SCU 2941 I NEED A OFFER!(01背包变形)
I NEED A OFFER! 64bit IO Format: %lld & %llu Submit Status Description Description Speakless ...
- HDU 4442 Physical Examination
Physical Examination Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- SCU 4440 分类: ACM 2015-06-20 23:58 16人阅读 评论(0) 收藏
SCU - 4440 Rectangle Time Limit: Unknown Memory Limit: Unknown 64bit IO Format: %lld & %llu ...
随机推荐
- string的内存本质
虽然没有研究过string的源代码,不过可以确定的是string的内存空间是在堆上开辟的,它自己负责释放空间,不用我们关系. 我们用一个动态分配的字符串指针初始化一个string对象retStr,它会 ...
- ACM选修hust 1075 组合+数学+期望值
Description Input Output Sample Input 2 2 1 0 1 1 0 3 1 0 1 1 1 0 1 1 1 0 Sample Output 0.500 1.125 ...
- CSS居中之美
关于居中,你会想到什么? div{margin: auto;} 常见的居中方法 水平居中 .demo{ text-align: center; margin: auto; position: abso ...
- SpringCloud(四)服务发现与消费:以ribbon为例
说明: ribbon是spring-cloud中作为服务消费者的一种角色,客户端可以通过它来对服务提供者的服务进行消费, 比如本例中是服务提供者注册到注册中心,服务提供者提供了一个服务接口,返回一个h ...
- 解决gridview row 左边序列号 显示不完全的技巧
放在主程序 入口处, public Form1() { InitializeComponent(); gridView1.IndicatorWidth = ; //<宽度值>官方推荐常用是 ...
- Tool1—安装配置Windows Live Writer
详细步骤请看:http://home.cnblogs.com/group/topic/8550.html . Windows Live Writer手工配置步骤(在博客园配置时输入用户名与密码会自动完 ...
- JQuery对RadioButton和CheckButton的操作
js对RadioButton和CheckButton的操作,在网站开发中会经常遇到,而JQuery操作RadioButton和CheckButton非常便捷.小编觉得网站开发人员有必要熟练掌握.所以小 ...
- php上传文件大小限制的方法详解
打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...
- OkHttp与Cookie及Cookie的持久化
http://blog.csdn.net/u011150924/article/details/52780931 http://blog.csdn.net/chen19960724/article/d ...
- [001] leap_stage
[Description] There is a number in each stages that indicates the most stages you can leap up. Now, ...