HDU 3987 求断开两点最小花费下的边数 最小割
来源:互联网 发布:网络摄像头带宽计算 编辑:程序博客网 时间:2024/04/30 10:59
题意:
给定n个点m条边(点标从0开始)
下面m行 u v d(边权) k(k=0表示单向,1表示双向)
问:
把0 和 n-1点断开 使得0点无法到达n-1点 需要删去多少条边(删边的花费为边权) 问在最小花费情况下,输出要删的边数
思路:
最小割裸题,以0为源点,n-1为汇点,边权改为 w* E(E>最大的边权) +1
最后最大流%E,就可以得到边数。
注意用 __int64
#include <iostream>#include <string.h>#include<stdio.h>#include<queue>using namespace std;#define ll __int64#define inf 1152921504606846976#define N 1005#define M 100010//N为点数 M为边数struct Edge{int from, to;ll cap;int nex;}edge[M*8];//注意这个一定要够大 不然会re 还有反向弧int head[N], edgenum;void addedge(int u, int v, ll cap){Edge E = { u, v, cap, head[u]};edge[ edgenum ] = E;head[u] = edgenum ++;Edge E2= { v, u, 0, head[v]};edge[ edgenum ] = E2;head[v] = edgenum ++;}int sign[N], s, t;bool BFS(int from, int to){memset(sign, -1, sizeof(sign));sign[from] = 0;queue<int>q;q.push(from);while( !q.empty() ){int u = q.front(); q.pop();for(int i = head[u]; i!=-1; i = edge[i].nex){int v = edge[i].to;if(sign[v]==-1 && edge[i].cap){sign[v] = sign[u] + 1, q.push(v);if(sign[to] != -1)return true;}}}return false;}int Stack[M*4], top, cur[M*4];ll dinic(){ll ans = 0;while( BFS(s, t) ){memcpy(cur, head, sizeof(head));int u = s;top = 0;while(1){if(u == t){ll flow = inf;int loc;//loc 表示 Stack 中 cap 最小的边for(int i = 0; i < top; i++)if(flow > edge[ Stack[i] ].cap){flow = edge[Stack[i]].cap;loc = i;}for(int i = 0; i < top; i++){edge[ Stack[i] ].cap -= flow;edge[Stack[i]^1].cap += flow;}ans += flow;top = loc;u = edge[Stack[top]].from;}for(int i = cur[u]; i!=-1; cur[u] = i = edge[i].nex)//cur[u] 表示u所在能增广的边的下标if(edge[i].cap && (sign[u] + 1 == sign[ edge[i].to ]))break;if(cur[u] != -1){Stack[top++] = cur[u];u = edge[ cur[u] ].to;}else{if( top == 0 )break;sign[u] = -1;u = edge[ Stack[--top] ].from;}}}return ans;}int main() {int n, m, T, Cas = 1;scanf("%d",&T);int u, v, k;ll d;while (T--) {scanf("%d %d", &n, &m);memset(head, -1, sizeof(head));ll E = 100001;while(m--){scanf("%d %d %I64d %d",&u, &v, &d, &k); d*=E; d++;addedge(u, v, d); if(k) addedge(v, u, d);}s = 0, t = n-1;printf("Case %d: %I64d\n", Cas++, dinic()%E);}return 0;}/*994 50 1 3 00 2 1 01 2 1 11 3 1 12 3 3 16 70 1 1 00 2 1 00 3 1 01 4 1 02 4 1 03 5 1 04 5 2 03 60 1 1 00 1 2 01 1 1 11 2 1 01 2 1 02 1 1 1*/
0 0
- HDU 3987 求断开两点最小花费下的边数 最小割
- hdu 3987(最小割的边数)
- HDU--3987[Harry Potter and the Forbidden Forest] 求最小割集中的最小边数
- hdu 3987(求边最少的最小割)
- HDU 6214 Smallest Minimum Cut(求最小割的最少边数)
- hdu Smallest Minimum Cut 边数最少的最小割
- hdu 3987 最小割
- DP求最小花费
- hdu 3987 Harry Potter and the Forbidden Forest//边数最小的最小割 2种解题方法
- HDU 6214 Smallest Minimum Cut【最小割的最小边数】
- 求网络的最小割
- hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
- hdu 3987 求割边最少的最小割
- hdu 3987 求割边最少的最小割
- hdu6214(求最小割最少边数)
- hdu3987(最小割最小边数)
- hdu 3987(求割边最小的最小割)
- 已知有向图任意两点的最短距离,求最小边数
- Java方法的可变参数类型
- Java MD5 32位加密代码
- 乌龟捉鸡
- 每天两道oracle笔试题+第七天:1、简述数据库的data block、extent、segement的区别?2、简述为何要使用索引?
- Eclipse中常用快键建
- HDU 3987 求断开两点最小花费下的边数 最小割
- OpenCV中的HOG+SVM物体分类
- android Camera拍照 及 MediaRecorder录像 预览图像差90度
- 玩转无线路由之DD-WRT基础扫盲
- poj 3107 Godfather(树形DP,点的个数较多, 删点使得剩余部分结点最多的最小值)
- 创业公司如何实施敏捷开发
- multimap的存储顺序研究
- MySQL问题解决:-bash:mysql:command not found
- MyEclipse + Maven开发Web工程的详细配置过程