BZOJ1693: [Usaco2007 Demo]Asteroids

n<=500 *n的格子,给m<=10000个格子有人,一炮可以清掉一行或一列的人(莫名的爽!)求最少几炮干掉所有人。

经典二分图模型!行成点,列成点,一个点就连接一行一列,表示这一行或这一列必选其一!

不喜欢匈牙利!跑网络流!

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 int n,m;
 9 #define maxn 1011
10 #define maxm 22011
11 struct Edge{int to,next,cap,flow;};
12 const int inf=0x3f3f3f3f;
13 struct Network
14 {
15     Edge edge[maxm];int first[maxn],le,n,s,t;
16     void clear(int n)
17     {
18         memset(first,0,sizeof(first));
19         le=2;this->n=n;
20     }
21     void in(int x,int y,int cap)
22     {
23         Edge &e=edge[le];
24         e.to=y;e.cap=cap;e.flow=0;
25         e.next=first[x];first[x]=le++;
26     }
27     void insert(int x,int y,int cap) {in(x,y,cap);in(y,x,0);}
28     int dis[maxn],cur[maxn],que[maxn],head,tail;
29     bool bfs()
30     {
31         memset(dis,0,sizeof(dis));
32         dis[s]=1;
33         que[head=(tail=1)-1]=s;
34         while (head!=tail)
35         {
36             const int now=que[head++];
37             for (int i=first[now];i;i=edge[i].next)
38             {
39                 Edge &e=edge[i];
40                 if (e.cap>e.flow && !dis[e.to])
41                 {
42                     dis[e.to]=dis[now]+1;
43                     que[tail++]=e.to;
44                 }
45             }
46         }
47         return dis[t];
48     }
49     int dfs(int x,int a)
50     {
51         if (x==t || !a) return a;
52         int flow=0,f;
53         for (int &i=cur[x];i;i=edge[i].next)
54         {
55             Edge &e=edge[i];
56             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
57             {
58                 e.flow+=f;
59                 edge[i^1].flow-=f;
60                 a-=f;
61                 flow+=f;
62                 if (!a) break;
63             }
64         }
65         return flow;
66     }
67     int Dinic(int s,int t)
68     {
69         this->s=s,this->t=t;
70         int ans=0;
71         while (bfs())
72         {
73             for (int i=1;i<=n;i++) cur[i]=first[i];
74             ans+=dfs(s,inf);
75         }
76         return ans;
77     }
78 }g;
79 int x,y;
80 int main()
81 {
82     scanf("%d%d",&n,&m);
83     g.clear(n*2+2);
84     int s=g.n-1,t=g.n;
85     for (int i=1;i<=n;i++) g.insert(s,i,1);
86     for (int i=n+1;i<=n*2;i++) g.insert(i,t,1);
87     for (int i=1;i<=m;i++)
88     {
89         scanf("%d%d",&x,&y);
90         g.insert(x,y+n,1);
91     }
92     printf("%d\n",g.Dinic(s,t));
93     return 0;
94 }
View Code

 

posted @ 2017-09-05 21:26  Blue233333  阅读(165)  评论(0编辑  收藏  举报