标签:random maze hdu 4067 最小费用流 贪心思想建图
2 2 1 1 2 2 1 2 3 5 6 1 4 1 2 3 1 2 5 4 5 5 3 2 3 3 2 6 7 2 4 7 6 3 4 10 5
Case 1: impossible Case 2: 27
这一题建图很巧妙,自己想不出来,解题思路参考这位大神Here
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define mod 1000000009 #define INF 100000 #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FREE(i,a,b) for(i = a; i >= b; i--) #define FRL(i,a,b) for(i = a; i < b; i++) #define FRLL(i,a,b) for(i = a; i > b; i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") typedef long long ll; using namespace std; const int MAXN = 105; const int MAXM = 100000; struct Edge { int to,next,cap,flow,cost; }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN],MIN[MAXN]; bool vis[MAXN]; int N; int n,m,s,t; int in[MAXN],out[MAXN]; void init(int n) { N=n; tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].to=v; edge[tol].cap=cap; edge[tol].cost=cost; edge[tol].flow=0; edge[tol].next=head[u]; head[u]=tol++; edge[tol].to=u; edge[tol].cap=0; edge[tol].cost=-cost; edge[tol].flow=0; edge[tol].next=head[v]; head[v]=tol++; } bool spfa(int s,int t) { queue<int>q; for (int i=0;i<N;i++) { dis[i]=INF; vis[i]=false; pre[i]=-1; } MIN[s]=INF; dis[s]=0; vis[s]=true; q.push(s); while (!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) { dis[v]=dis[u] + edge[i].cost; pre[v]=i; MIN[v]=min(edge[i].cap-edge[i].flow,MIN[u]); if (!vis[v]) { vis[v]=true; q.push(v); } } } } return pre[t]!=-1; } //返回的是最大流,cost存的是最小费用 int minCostMaxflow(int s,int t,int &cost) { int flow=0; cost=0; while (spfa(s,t)) { int Min=MIN[t]; for (int i=pre[t];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } flow+=Min; } return flow; } int main() { #ifndef ONLINE_JUDGE freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin); #endif int i,j,T; int u,v,a,b,sum,Case=1; sf(T); while (T--) { sum=0; memset(in,0,sizeof(in)); scanf("%d%d%d%d",&n,&m,&s,&t); init(n+2); for (i=0;i<m;i++) { scanf("%d%d%d%d",&u,&v,&a,&b); if (a<=b) { sum+=a; addedge(v,u,1,b-a); --in[u];++in[v]; } else { sum+=b; addedge(u,v,1,a-b); // in[v]++;in[u]--; } } in[s]++; in[t]--; int tmp=0; for (int i=1;i<=n;i++) { if (in[i]>0) addedge(0,i,in[i],0); else addedge(i,N-1,-in[i],0),tmp-=in[i]; } int x,ans; x=minCostMaxflow(0,N-1,ans); pf("Case %d: ", Case++); if (x==tmp) printf("%d\n",ans+sum); else printf("impossible\n"); } return 0; } /* 2 2 1 1 2 2 1 2 3 5 6 1 4 1 2 3 1 2 5 4 5 5 3 2 3 3 2 6 7 2 4 7 6 3 4 10 5 */
版权声明:本文为博主原创文章,未经博主允许不得转载。
Random Maze (hdu 4067 最小费用流 好题 贪心思想建图)
标签:random maze hdu 4067 最小费用流 贪心思想建图
原文地址:http://blog.csdn.net/u014422052/article/details/46839223