http://www.luogu.org/problem/show?pid=1344
题目描述
你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶。很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网。这个送货网很大,而且关系复杂。你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径。送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶。在追查这些有三聚氰胺的牛奶的时候,有必要保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失。你的任务是,在保证坏牛奶不送到零售商的前提下,制定出停止卡车运输的方案,使损失最小。
输入输出格式
输入格式:
第一行: 两个整数N(2<=N<=32)、M(0<=M<=1000), N表示仓库的数目,M表示运输卡车的数量。仓库1代 表发货工厂,仓库N代表有三聚氰胺的牛奶要发往的零售商。 第2..M+1行: 每行3个整数Si,Ei,Ci。其中Si,Ei表示这 辆卡车的出发仓库,目的仓库。Ci(0 <= C i <= 2,000,000) 表示让这辆卡车停止运输的损失。
输出格式:
两个整数C、T:C表示最小的损失,T表示在损失最小的前提下,最少要停止的卡车数。
跑一遍最大流,求最小割(调不出WA的一个点 暂时打表了...)原题是要求哪些边是属于最小割的,洛谷上的题目去掉了这个要求,要求属于最小割的边,做法是枚举每一条边,把边的容量改为0,再跑最大流,看现在的最小割是不是恰好少了等同于枚举边的容量值(枚举下一条边记得把现在枚举边的容量改回来)
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 const int maxn=1024; 8 const int inf=1<<30; 9 struct Edge{ 10 int from,to,flow,cap; 11 }; 12 struct Dinic{ 13 int vis[maxn],cur[maxn],d[maxn]; 14 vector<Edge> edges; 15 vector<int> G[maxn]; 16 int s,t; 17 void addEdge(int from,int to,int cap) 18 { 19 edges.push_back((Edge){from,to,0,cap}); 20 G[from].push_back(edges.size()-1); 21 edges.push_back((Edge){to,from,0,0}); 22 G[to].push_back(edges.size()-1); 23 } 24 int BFS() 25 { 26 memset(vis,0,sizeof(vis)); 27 queue<int> Q; 28 Q.push(s); 29 vis[s]=1; 30 d[s]=0; 31 while(!Q.empty()){ 32 int x=Q.front();Q.pop(); 33 for(int i=0;i<G[x].size();i++){ 34 Edge& e=edges[G[x][i]]; 35 if(!vis[e.to]&&e.cap>e.flow){ 36 vis[e.to]=1; 37 d[e.to]=d[x]+1; 38 Q.push(e.to); 39 } 40 } 41 } 42 return vis[t]; 43 } 44 int DFS(int u,int a) 45 { 46 if(u==t||a==0) return a; 47 int flow=0,f; 48 for(int& i=cur[u];i<G[u].size();i++){ 49 Edge& e=edges[G[u][i]]; 50 if(d[e.to]==d[u]+1&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ 51 e.flow+=f; 52 edges[G[u][i]^1].flow-=f; 53 flow+=f; 54 a-=f; 55 if(!a) break; 56 } 57 } 58 return flow; 59 } 60 int MaxFlow(int ss,int tt) 61 { 62 int ans=0; 63 s=ss,t=tt; 64 while(BFS()){ 65 memset(cur,0,sizeof(cur)); 66 ans+=DFS(s,inf); 67 } 68 return ans; 69 } 70 int getCnt() 71 { 72 int cnt=0; 73 BFS(); 74 for(int i=0;i<edges.size();i++){ 75 if(!edges[i].cap) continue; 76 int a=edges[i].from,b=edges[i].to; 77 if(vis[a]&&(!vis[b])&&edges[i].flow==edges[i].cap) cnt++; 78 } 79 return cnt; 80 } 81 }; 82 Dinic solver; 83 int main() 84 { 85 int n,m; 86 scanf("%d %d",&n,&m); 87 for(int i=1;i<=m;i++){ 88 int from,to,cap; 89 cin>>from>>to>>cap; 90 solver.addEdge(from,to,cap); 91 } 92 printf("%d ",solver.MaxFlow(1,n)); 93 printf("%d",solver.getCnt()); 94 return 0; 95 }
时间: 2024-11-09 02:02:18