# BZOJ1741: [Usaco2005 nov]Asteroids 穿越小行星群

n<=500,n*n网格给m<=10000个点，每次发射子弹打掉一行或一列的点，求最少几发子弹。

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

posted @ 2017-07-28 16:22  Blue233333  阅读(144)  评论(0编辑  收藏  举报