有道目前崇尚小团队开发工作,因为团队越小,工作效率越高,团队之间不可避免存在合作,为了把高内聚低耦合的思想用在工作中,略去。
分析:输入定点数,边数,顶点一和顶点二,以及所有的边,刚开始以为是,找到最短路,然后记录路径,进行统计,发现这个搜索就行,再仔细一想,有源点和汇点,这不是最大流最小割么!然后,发现不会写dinic算法,之前写过,就是一个深搜加广搜,然后就完了,但是现场这么紧张的写,是写不出来的,所以从网上直接找模板做吧。
1. 刚开始,添加源点和汇点,到输入的一对顶点,这个边上的流量设为100 + 10,其他输入的边的流量为1,然后就去交了,完全错误,错误的原因是:我自己把它当做有向图来处理的。其实是无向图,修改后过了80%,后来也没调出来,就结束了。
考试结束后仔细分析下:
1.这个图是无向图,使用最大流最小割的时候注意边上流量的设置。这个题目能用普通的枚举做法么,要是可以,应该怎么枚举。
2.题意强调任何2个团队只有一个接口人,这个描述应该包含很多性质吧,我不知道怎么做,这个性质应该怎么利用,图是无向图,没有出边和入边的概念。
3.由于去掉一个点,就是去掉一个团队,这样这个点应该有流量为1的限制,所以给每一个顶点(除去源点和汇点)后面添加一条边和一个点,这条边的流量应该为1.注意源点和汇点要单独处理。
4. 由于是无向图,给定的2个顶点,任意一个顶点作为源点或者汇点都可以,还是怎么做?这个也不知道怎么处理。
我想到的几点就上面这样,也没有地方去测试程序的正确性,如果你能找到原题,请告知!就这样吧。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 9 const int mn=422; 10 const int mm=10000; 11 const double oo=999999; 12 int node, st, sd, edge; 13 int reach[mm], nxt[mm]; 14 double flow[mm]; 15 int adj[mn], work[mn], dis[mn], que[mn]; 16 17 inline void init(int _node, int _st, int _sd) 18 { 19 node=_node, st=_st, sd=_sd; 20 for(int i=0; i<node; i++) 21 adj[i]=-1; 22 edge=0; 23 } 24 25 inline void addedge(int u, int v, double c1, double c2) 26 { 27 reach[edge]=v, flow[edge]=c1, nxt[edge]=adj[u],adj[u]=edge++; 28 reach[edge]=u, flow[edge]=c2, nxt[edge]=adj[v],adj[v]=edge++; 29 } 30 31 bool bfs() 32 { 33 int i,u,v,l,r=0; 34 for(i=0; i<node; ++i)dis[i]=-1; 35 dis[que[r++]=st]=0; 36 for(l=0; l<r; ++l) 37 for(i=adj[u=que[l]]; i>=0; i=nxt[i]) 38 if(flow[i]&&dis[v=reach[i]]<0) 39 { 40 dis[que[r++]=v]=dis[u]+1; 41 if(v==sd)return 1; 42 } 43 return 0; 44 } 45 46 double dfs(int u,double exp) 47 { 48 if(u==sd) return exp; 49 double tmp; 50 for(int &i=work[u],v; i>=0; i=nxt[i]) 51 if(flow[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=dfs(v,min(exp,flow[i])))>0) 52 { 53 flow[i]-=tmp; 54 flow[i^1]+=tmp; 55 return tmp; 56 } 57 return 0; 58 } 59 60 double Dinic() 61 { 62 double max_flow=0, flow; 63 while(bfs()) 64 { //cout << "asd" << endl; 65 for(int i=0; i<node; i++) work[i]=adj[i]; 66 while(flow=dfs(st,oo)) { 67 //cout << flow << endl; 68 max_flow+=flow; 69 } 70 } 71 return max_flow; 72 } 73 //上面从网上搜索的,注意修改顶点数,边数,这里边数是2倍,注意节点的编号,从0开始。 74 //当然,你必须知道dinic算法的逻辑才行。 75 int main() 76 { 77 freopen("test.in", "r", stdin); 78 int n, m, k, t1, t2; 79 scanf("%d%d%d%d",&n,&m,&t1, &t2); 80 int s, e; 81 int len = n; 82 s = 0; e = n * 2 + 1; 83 n = n * 2 + 2; 84 85 init(n,s,e); 86 addedge(s, t1 + len, 150, 0); 87 addedge(t2, e, 150, 0); 88 for (int i = 1; i <= len; i++) { 89 //if(i == t1 || i == t2) continue; 90 addedge(i, i + len, 1, 1); 91 //cout << i << " " << i + len << endl; 92 } 93 int x, y; 94 for (int i = 0; i < m; i++) { 95 scanf("%d%d", &x, &y); 96 97 addedge(x + len, y, 1, 1); 98 //cout << x + len << " " << y << endl; 99 } 100 double ans=Dinic(); 101 printf("%d\n",(int)ans); 102 103 return 0; 104 }
时间: 2024-10-13 10:14:50