二分图的最小点权覆盖。

非常感谢巨巨@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的更多相关文章

  1. SCU 4442 party 二分图最大点权独立集

    每个青蛙喝黑茶或者红茶或者都可以喝 M个矛盾关系 有矛盾的不能喝同种茶 但你可以花费Wi使得这个青蛙消除所有矛盾 把矛盾当作边 青蛙当作点 如果这两个青蛙只喝不同的一种茶就不建边 题目中保证了不存在奇 ...

  2. 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 ...

  3. ACM:SCU 4437 Carries - 水题

    SCU 4437  Carries Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practice  ...

  4. ACM: SCU 4438 Censor - KMP

     SCU 4438 Censor Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practice D ...

  5. ACM: SCU 4440 Rectangle - 暴力

     SCU 4440 Rectangle Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practic ...

  6. SCU 4424(求子集排列数)

    A - A Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice ...

  7. SCU 2941 I NEED A OFFER!(01背包变形)

    I NEED A OFFER!     64bit IO Format: %lld & %llu Submit Status Description Description Speakless ...

  8. HDU 4442 Physical Examination

    Physical Examination Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  9. SCU 4440 分类: ACM 2015-06-20 23:58 16人阅读 评论(0) 收藏

    SCU - 4440 Rectangle Time Limit: Unknown   Memory Limit: Unknown   64bit IO Format: %lld & %llu ...

随机推荐

  1. OpenCV---色彩空间(一)

    颜色空间:用三种或者更多特征来指定颜色的方法,被称为颜色空间或者颜色模型 1.RGB(OpenCV中为BGR): 一幅图像由三个独立的图像平面或者通道构成:红.蓝.绿(以及可选项:透明度alpha通道 ...

  2. mysql数据库使用sql命令窗口查询的数据,改成sql语句导入到mysql数据库中

    1.查询语句为select * from t_table;导出的数据格式如下: 2.将数据文本备份,然后使用NOTEPAD++打开,然后只拷贝数据到新建txt中,然后进行如下替换: 1)将“ | ”分 ...

  3. CSS3笔记-加强版

    属性选择器:   E[attr]只使用属性名,但没有确定任何属性值 E[attr="value"]指定属性名,并指定了该属性的属性值 E[attr~="value&quo ...

  4. max-device-width和max-width的区别

    比如用媒体查询响应输出@media (max-width: 767px),用谷歌浏览器手机测试插件显示并无变化,其实关键在于max-device-width和max-width,以下摘抄↓ max-d ...

  5. 论文里有公式?用texlive+texstudio(windows下)

    要写论文了,但论文里有一大堆公式,感觉很麻烦,经过询问同学知道有tex这么个东西,可以像写代码一样写论文,许多论文的格式都有相关的模板,所以学习一下,这里记录一下环境安装. texlive和texst ...

  6. HDU 2082 找单词 (普通母函数)

    题目链接 Problem Description 假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于 ...

  7. koa源码阅读[1]-koa与koa-compose

    接上次挖的坑,对koa2.x相关的源码进行分析 第一篇.不得不说,koa是一个很轻量.很优雅的http框架,尤其是在2.x以后移除了co的引入,使其代码变得更为清晰. express和koa同为一批人 ...

  8. 贪心算法_01背包问题_Java实现

    原文地址:http://blog.csdn.net/ljmingcom304/article/details/50310789 本文出自:[梁敬明的博客] 1.贪心算法 什么是贪心算法?是指在对问题进 ...

  9. 76.ZYNQ-用PS控制DDR3内存读写

    本编文章的目的主要用简明的方法对DDR3进行读写,当然这种方式每次读写都需要CPU干预,效率是比较低的,但是这是学习的过程吧. 本系列文章尽可能的让每一个实验都相对独立,过程尽可能保证完整性,保证实验 ...

  10. final修饰的变量是引用不能改变还是引用的对象不能改变

    我们都知道final修饰变量时 会变为常量,但是使 用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 下面让我们来看这段代码: /** * 验证final修饰的变量是引用不能变, ...