【usaco】patrol
很长时间都没想出来的简单题,看了题解才写出来,还是naive
原题:
FJ有个农场,其中有n块土地,由m条边连起来。FJ的养牛场在土地1,在土地n有个新开张的雪糕店。Bessie经常偷偷溜到雪糕店,当Bessie去的时候,FJ就要跟上她。但是Bessie很聪明,她在从雪糕店返回时不会经过去雪糕店时经过的农场,因此FJ总是抓不住Bessie。
为了防止Bessie生病,FJ决定把一些诚实的狗放在一些土地(1和n除外)上,使Bessie无法在满足每块土地最多只经过一次的条件的情况下,从养牛场溜到雪糕店然后又溜回养牛场。
求出FJ最少要放多少只狗。数据保证1和n间没有直接的连边。
n<=1000,m<=10000。
拆点来控制每个点只经过一次
先搞一个从源到汇每个点只经过一次的最小割,然后这个最小割-1,就是答案,似乎因为少拦一个点就相当于放开了另一条回去的路?
图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通图不一定连通
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int oo=168430090; 8 int read(){int z=0,mark=1; char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-')mark=-1; ch=getchar();} 10 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 11 return z*mark; 12 } 13 struct ddd{int next,y,value,fan;}e[510000];int LINK[2100],ltop=0; 14 inline void insert(int x,int y,int z){ 15 e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;e[ltop].value=z;e[ltop].fan=ltop+1; 16 e[++ltop].next=LINK[y];LINK[y]=ltop;e[ltop].y=x;e[ltop].value=0;e[ltop].fan=ltop-1; 17 } 18 int n,m; 19 int s=0,t; 20 int level[2100]; 21 int dui[2100],tou=0; 22 bool get_level(){ 23 memset(level,-1,sizeof(level)); 24 dui[tou=1]=s; level[s]=0; 25 for(int k=1;k<=tou;k++) 26 for(int i=LINK[dui[k]];i;i=e[i].next)if(e[i].value && level[e[i].y]==-1){ 27 dui[++tou]=e[i].y; 28 level[e[i].y]=level[dui[k]]+1; 29 } 30 return level[t]!=-1; 31 } 32 int get_maxflow(int x,int y){ 33 if(x==t) return y; 34 int maxflow=0,flow=0; 35 for(int i=LINK[x];i;i=e[i].next)if(e[i].value && level[e[i].y]==level[x]+1) 36 if(flow=get_maxflow(e[i].y,min(y-maxflow,e[i].value))){ 37 maxflow+=flow; 38 e[i].value-=flow,e[e[i].fan].value+=flow; 39 } 40 if(!maxflow) level[x]=-1; 41 return maxflow; 42 } 43 int dinic(){ 44 int flow,bowl=0; 45 while(get_level()) 46 while(flow=get_maxflow(s,oo)) 47 bowl+=flow; 48 return (bowl) ? bowl : 1;//注意图有可能不连通!!! 49 } 50 int main(){//freopen("ddd.in","r",stdin); 51 cin>>n>>m; 52 t=n*2+1; 53 int _left,_right; 54 insert(s,1,oo),insert(n+n,t,oo); 55 for(int i=2;i<n;i++) insert(i,i+n,1); 56 insert(1,1+n,oo),insert(n,n+n,oo); 57 while(m --> 0){ 58 _left=read(),_right=read(); 59 insert(_left+n,_right,oo),insert(_right+n,_left,oo); 60 } 61 cout<<dinic()-1<<endl; 62 return 0; 63 }