题意:N个点。M条边(2 <= N <= 1000 , 0 <= M <= 10^5),每一个点有个权值W(0 <= W <= 10^5),现要去除一些点(不能去掉点0),使得结点 0 与结点 N - 1 不连通,求去掉的点的最小权值和。

题目链接:http://cstest.scu.edu.cn/soj/problem.action?id=3254

——>>这是很明显的最小点权割。。

建图方案:

1)将全部点 i 拆成 i 和 i + N。i -> i + N(容量为Wi)

2)原图中的边 i -> j 变成 i + N -> j(容量为无穷大)

3)0 -> 0 + N(由于原图中的边可能有涉及到0 -> x,这时会拆0)

接着,依据最小割最大流定理。求得最小割。。(又换命名法了我。囧。。)

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm> using std::min;
using std::queue; const int MAXN = 1000 * 2 + 10;
const int MAXM = 2 * (1000 + 100000) + 10;
const int INF = 0x3f3f3f3f; struct EDGE
{
int to;
int cap;
int flow;
int nxt;
}; int N, M;
int hed[MAXN], nxt[MAXM], S, T;
int cur[MAXN], h[MAXN];
bool vis[MAXN];
int ecnt;
EDGE edge[MAXM]; void Init()
{
ecnt = 0;
memset(hed, -1, sizeof(hed));
} void AddEdge(int u, int v, int cap)
{
edge[ecnt].to = v;
edge[ecnt].cap = cap;
edge[ecnt].flow = 0;
edge[ecnt].nxt = hed[u];
hed[u] = ecnt++;
} bool Bfs()
{
queue<int> qu; memset(vis, 0, sizeof(vis));
qu.push(S);
vis[S] = true;
h[S] = 0;
while (!qu.empty())
{
int u = qu.front();
qu.pop();
for (int e = hed[u]; e != -1; e = edge[e].nxt)
{
int v = edge[e].to;
if (!vis[v] && edge[e].flow < edge[e].cap)
{
h[v] = h[u] + 1;
vis[v] = true;
qu.push(v);
}
}
} return vis[T];
} int Dfs(int u, int cap)
{
if (u == T || cap == 0) return cap; int flow = 0, subFlow;
for (int e = cur[u]; e != -1; e = edge[e].nxt)
{
cur[u] = e;
int v = edge[e].to;
if (h[v] == h[u] + 1 && (subFlow = Dfs(v, min(cap, edge[e].cap - edge[e].flow))) > 0)
{
flow += subFlow;
edge[e].flow += subFlow;
edge[e ^ 1].flow -= subFlow;
cap -= subFlow;
if (cap == 0) break;
}
} return flow;
} int Dinic()
{
int flow = 0; while (Bfs())
{
memcpy(cur, hed, sizeof(hed));
flow += Dfs(S, INF);
} return flow;
} void Read()
{
int W;
scanf("%d%d", &N, &M);
for (int i = 1; i < N; ++i)
{
scanf("%d", &W);
AddEdge(i, i + N, W);
AddEdge(i + N, i, 0);
}
int P, Q;
for (int i = 0; i < M; ++i)
{
scanf("%d%d", &P, &Q);
AddEdge(P + N, Q, INF);
AddEdge(Q, P + N, 0);
}
AddEdge(0, N, INF);
AddEdge(N, 0, 0);
S = 0;
T = 2 * N - 1;
} void Solve()
{
printf("%d\n", Dinic());
} int main()
{
int T; scanf("%d", &T);
while (T--)
{
Init();
Read();
Solve();
} return 0;
}

scu - 3254 - Rain and Fgj(最小点权割)的更多相关文章

  1. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

  2. POJ3308 Paratroopers(最小割/二分图最小点权覆盖)

    把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...

  3. HDU 3491 最小点权割集

    题意:有n个城市,m条双向边,有一群小偷从s前往t偷东西,警察叔叔们想要逮捕小偷们,现在告诉你在每座城市需要多少警察才能抓住这个城市的小偷,为什么说这个城市,因为小偷们会分开跑:然后题目还说不能在s和 ...

  4. POJ2125 Destroying The Graph(二分图最小点权覆盖集)

    最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...

  5. POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)

                                                          Destroying The Graph Time Limit: 2000MS   Memo ...

  6. POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)

    题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...

  7. POJ 3308 Paratroopers (对数转换+最小点权覆盖)

    题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...

  8. POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割

    思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...

  9. poj3308 Paratroopers --- 最小点权覆盖-&gt;最小割

    题目是一个非常明显的二分图带权匹配模型, 加入源点到nx建边,ny到汇点建边,(nx.ny)=inf建边.求最小割既得最小点权覆盖. 在本题中因为求的是乘积,所以先所有取log转换为加法,最后再乘方回 ...

随机推荐

  1. unity3d ngui-TweenRotation-TweenPosition-TweenScale

    using UnityEngine; using System.Collections; public class TweenFlipCARDS : MonoBehaviour { private f ...

  2. android Activity切换动画效果

    为Activity设置左右进出的效果,能够通过在Mainfest.xml文件里设置主题的方式来实现.还能够使用java代码. 一.设置样式 先看看实现动画的样式: <style name=&qu ...

  3. VC/MFC 在ListCtl 控件中随鼠标移动提示单元格信息

    BEGIN_MESSAGE_MAP(CTipListCtrl, CListCtrl) //{{AFX_MSG_MAP(CTipListCtrl) ON_WM_MOUSEMOVE() ON_WM_DES ...

  4. java中synchronized的使用方法与具体解释

    Java语言的keyword.当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多仅仅有一个线程运行该段代码. 一.当两个并发线程訪问同一个对象object中的这个synchronized ...

  5. JSP的include指令

    JSP的include 指令:向当前页面中插入的一个静态文件的内容. 在test5.jsp里面 <%@ include file="test5_1.jsp" %> 新建 ...

  6. KMP(Knuth-Morris-Pratt)算法

    一.朴素匹配算法 也就是暴力匹配算法.设匹配字符串的长度为n,模式串的长度为m,在最坏情况下,朴字符串匹配算法执行时间为O((n - m + 1)m). 假设m = n / 2, 那么该算法的复杂度就 ...

  7. 二进制搜索方法C++通用执行

    算法很easy.直接附着到代码它 #include <iostream> using namespace std; template<typename T> int binar ...

  8. CDOJ 1221 Ancient Go

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1221 题目分类:dfs 代码: #include<bits/stdc++.h> using na ...

  9. 让qt应用程序支持触摸

    一.设备驱动 我的触摸屏是usb接口的 可以参考下这2篇文件 http://blog.csdn.net/paomadi/article/details/8754783 usb触摸屏 http://bl ...

  10. 建立地方Jekyll周边环境

    近期使用github建立一个博客,只是要了解markdown语法,因为markdown后写的不是立即可见.所以,每一个成品都要经过在线调试,在线调试已经上线的文章,每次上线有反复git add, gi ...