bzoj1412

比较裸的流了。。显然是最小割,S连狼=inf,羊连T=inf,狼羊和空地间=1,然后跑就行了,dinic略慢。。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<ctime>
 5 #include<cmath>
 6 #include<iostream>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<stack>
10 #include<set>
11 #define clr(a,x) memset(a,x,sizeof(a))
12 #define rep(i,l,r) for(int i=(l);i<(r);i++)
13 using namespace std;
14 typedef long long ll;
15 typedef pair<int,int> pii;
16 #define mkp(a,b) make_pair(a,b)
17 int read(){
18     int ans=0,f=1;
19     char c=getchar();
20     while(!isdigit(c)){
21         if(c=='-') f=-1;
22         c=getchar();
23     }
24     while(isdigit(c)){
25         ans=ans*10+c-'0';
26         c=getchar();
27     }
28     return ans*f;
29 }
30 const int maxn=109,inf=0x3fffffff;
31 int S,T,n,m,a[maxn][maxn],d[maxn*maxn];
32 #define cnt(a,b) (((a)-1)*m+(b))
33 struct edge{
34     int v,w;
35     edge*next,*r;
36 }e[maxn*maxn<<3],*fir[maxn*maxn],*cur[maxn*maxn],*pt=e;
37 void add(int u,int v,int w){
38     pt->v=v;pt->w=w;
39     pt->next=fir[u];
40     fir[u]=pt++;
41 }
42 void addedge(int u,int v,int w){
43     add(u,v,w);add(v,u,0);
44     fir[u]->r=fir[v];fir[v]->r=fir[u];
45 }
46 bool bfs(){
47     queue<int>Q;Q.push(S);
48     clr(d,0);d[S]=1;
49     while(!Q.empty()){
50         int x=Q.front();Q.pop();
51         for(edge*e=fir[x];e;e=e->next){
52             if(e->w&&!d[e->v]){
53                 d[e->v]=d[x]+1;Q.push(e->v);
54             }
55         }
56     }
57     return d[T];
58 }
59 int dfs(int x,int w){
60     if(x==T||!w) return w;
61     int f=0;
62     for(edge*&e=cur[x];e;e=e->next){
63         if(e->w&&d[e->v]==d[x]+1){
64             int g=dfs(e->v,min(e->w,w));
65             if(g>0){
66                 f+=g;
67                 e->w-=g;
68                 e->r->w+=g;
69                 if(!(w-=g)) break;
70             }
71         }
72     }
73     return f;
74 }
75 int maxflow(){
76     int ans=0;
77     while(bfs()){
78         rep(i,S,T+1) cur[i]=fir[i];
79         ans+=dfs(S,inf);
80     }
81     return ans;
82 }
83 int main(){
84     n=read();m=read();S=0;T=n*m+1;
85     rep(i,1,n+1)
86         rep(j,1,m+1) a[i][j]=read();
87     rep(i,1,n+1)
88         rep(j,1,m+1){
89             if(a[i][j]==1) addedge(S,cnt(i,j),inf);
90             if(a[i][j]==2) addedge(cnt(i,j),T,inf);
91             if(i-1>0&&(a[i-1][j]!=a[i][j]||!(a[i-1][j]|a[i][j]))) addedge(cnt(i-1,j),cnt(i,j),1);
92             if(i+1<=n&&(a[i+1][j]!=a[i][j]||!(a[i+1][j]|a[i][j]))) addedge(cnt(i+1,j),cnt(i,j),1);
93             if(j-1>0&&(a[i][j-1]!=a[i][j]||!(a[i][j-1]|a[i][j]))) addedge(cnt(i,j-1),cnt(i,j),1);
94             if(j+1<=m&&(a[i][j+1]!=a[i][j]||!(a[i][j+1]|a[i][j]))) addedge(cnt(i,j+1),cnt(i,j),1);
95         }
96     printf("%d\n",maxflow());
97     return 0;
98 }
View Code

1412: [ZJOI2009]狼和羊的故事

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1944  Solved: 1014
[Submit][Status][Discuss]

Description

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

Input

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

Output

文件中仅包含一个整数ans,代表篱笆的最短长度。

Sample Input

2 2
2 2
1 1

Sample Output

2

数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100

HINT

 

Source

 
[Submit][Status][Discuss]

 

posted @ 2015-11-26 22:03  ChenThree  阅读(122)  评论(0编辑  收藏  举报