Description
Input
Output
Sample Input
3 4 5 0 1 3 0 0 2 1 0 1 2 1 1 1 3 1 1 2 3 3 1 6 7 0 1 1 0 0 2 1 0 0 3 1 0 1 4 1 0 2 4 1 0 3 5 1 0 4 5 2 0 3 6 0 1 1 0 0 1 2 0 1 1 1 1 1 2 1 0 1 2 1 0 2 1 1 1
Sample Output
Case 1: 3 Case 2: 2 Case 3: 2 题意: 给出一个混合图,求要使s不能到达t,至少应该删除哪些边,使得删除的边的边权和最小,而且要求删除的边数达到最小; 题解: 很典型的最小割题目,不过题目在最小割的基础上添加了一个条件,就是要求割边尽可能的小. 首先我们可以求出混合图的最大流,最小割等于最大流, 然后对于割边的处理,可以这样做.将每条边的边权加1,再跑一次最大流. 这样可以求出割边最小的那个割集,因为割边越多,最小割会越大,假设存在割边 更小的割集,那么就你跑最大流就会跑出更小的流量出来. 最后直接两次最大流的结果相减即为答案; AC代码:/* *********************************************** Author :xdlove Created Time :2015年07月31日 星期五 12时37分29秒 File Name :a.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; /**宏定义类 * **/ #define FOR(i,s,t) for(int i = (s); i < (t); i++) #define FOR_REV(i,s,t) for(int i = (s - 1); i >= (t); i--) #define mid ((l + r) >> 1) #define lson l,mid,u<<1 #define rson mid+1,r,u<<1|1 #define ls u<<1 #define rs u<<1|1 typedef long long ll; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const double pi = acos(-1.0); /**输入输出挂类模板 * **/ class Fast { public: inline void rd(int &ret) { char c; int sgn; if(c = getchar(),c == EOF) return; while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(),c >= '0' && c <= '9') ret = ret * 10 + c - '0'; ret *= sgn; } public: inline void pt(int x) { if(x < 0) { putchar('-'); x = -x; } if(x > 9) pt(x / 10); putchar(x % 10 + '0'); } }; Fast in,out; const int MAXN = 1e3 + 5; const int MAXM = 1e5 * 2 + 5; struct Node { int from,to,next; int cap; }edge[MAXM * 2]; int tol; int Head[MAXN]; int que[MAXN]; int dep[MAXN]; //dep为点的层次 int stack[MAXN];//stack为栈,存储当前增广路 int cur[MAXN];//存储当前点的后继 void Init() { tol = 0; memset(Head,-1,sizeof(Head)); } void add_edge(int u, int v, int w) { edge[tol].from = u; edge[tol].to = v; edge[tol].cap = w; edge[tol].next = Head[u]; Head[u] = tol++; edge[tol].from = v; edge[tol].to = u; edge[tol].cap = 0; edge[tol].next = Head[v]; Head[v] = tol++; } int BFS(int start, int end) { int front, rear; front = rear = 0; memset(dep, -1, sizeof(dep)); que[rear++] = start; dep[start] = 0; while (front != rear) { int u = que[front++]; if (front == MAXN)front = 0; for (int i = Head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && dep[v] == -1) { dep[v] = dep[u] + 1; que[rear++] = v; if (rear >= MAXN)rear = 0; if (v == end)return 1; } } } return 0; } int dinic(int start, int end) { int res = 0; int top; while (BFS(start, end)) { memcpy(cur, Head, sizeof(Head)); int u = start; top = 0; while (true) { if (u == end) { int min = INF; int loc; for (int i = 0; i < top; i++) if (min > edge[stack[i]].cap) { min = edge[stack[i]].cap; loc = i; } for (int i = 0; i < top; i++) { edge[stack[i]].cap -= min; edge[stack[i] ^ 1].cap += min; } res += min; top = loc; u = edge[stack[top]].from; } for (int i = cur[u]; i != -1; cur[u] = i = edge[i].next) if (edge[i].cap != 0 && dep[u] + 1 == dep[edge[i].to]) break; if (cur[u] != -1) { stack[top++] = cur[u]; u = edge[cur[u]].to; } else { if (top == 0)break; dep[u] = -1; u = edge[stack[--top]].from; } } } return res; } struct RNode { int u,v,c,d; RNode(int u,int v,int c,int d) : u(u),v(v),c(c),d(d) {} RNode(){} }p[MAXM]; void Creatgraph(int m) { Init(); FOR(i, 0, m) { add_edge(p[i].u,p[i].v,p[i].c + 1); if(p[i].d) add_edge(p[i].v,p[i].u,p[i].c + 1); } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T,cnt = 0; cin>>T; while(T--) { int n,m; Init(); scanf("%d %d",&n,&m); FOR(i, 0, m) { int u,v,c,d; in.rd(u),in.rd(v),in.rd(c),in.rd(d); add_edge(u,v,c); if(d) add_edge(v,u,c); p[i] = RNode(u,v,c,d); } int ans = dinic(0,n - 1); //cout<<ans<<endl; Creatgraph(m); printf("Case %d: %d\n",++cnt,dinic(0,n - 1) - ans); } return 0; }