1. 程式人生 > >POJ3041:Asteroids——題解

POJ3041:Asteroids——題解

bool ble struct mat 它的 href tchar 二分圖匹配 spa

http://poj.org/problem?id=3041

題目大意:激光可以幹掉一整行或一整列隕石,求最少激光次數。

——————————————————

二分圖匹配,對於每一個隕石將它的橫縱坐標相連。

然後發現我們需要將每一條邊中的端點之一都覆蓋掉,就是最小點覆蓋。

有結論最小點覆蓋=最大匹配數。

然後本題就切了。

#include <cstdio>
#include 
<iostream> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int M=10010; const int N=1010; const int INF=2147483640; inline int read(){ int X=0,w=0;char ch=0; while(ch<0||ch>9){w|=ch==-;ch=getchar();} while(ch>=0
&&ch<=9)X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ int next; int to; int w; }edge[N*2+M*2]; int head[N],cnt=-1; void add(int u,int v,int w){//u起點v終點w容量 cnt++; edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]
=cnt; return; } int lev[N],cur[N];//lev層數,cur[i]為以i為起點的邊的編號 bool bfs(int m){//強制1為源點,m為匯點 int dui[m],r=0;//隊列和右指針 for(int i=1;i<=m;i++){//初始化 lev[i]=-1; cur[i]=head[i]; } dui[0]=1,lev[1]=0; int u,v;//u起點v終點 for(int l=0;l<=r;l++){//左指針 u=dui[l]; for(int e=head[u];e!=-1;e=edge[e].next){ v=edge[e].to; if(edge[e].w>0&&lev[v]==-1){//1.能走 2.未分層 lev[v]=lev[u]+1; r++; dui[r]=v;//v入隊 if(v==m)return 1;//分層完畢 } } } return 0;//無法分層 } int dinic(int u,int flow,int m){//u當前點,flow為下面的點能夠分配多大的流量,m終點 if(u==m)return flow;//終點直接全流入 int res=0,delta;//res實際流量 for(int &e=cur[u];e!=-1;e=edge[e].next){//‘&‘相當於cur[u]=e;即流滿的邊不會再被掃一次 int v=edge[e].to; if(edge[e].w>0&&lev[u]<lev[v]){//只能從低層往高層流 delta=dinic(v,min(edge[e].w,flow-res),m); if(delta>0){//如果增廣 edge[e].w-=delta;//正向邊容量減少 edge[e^1].w+=delta;//反向邊仍量增加(暗示退流) res+=delta;//擴張流量增加 if(res==flow)break;//可流的都流完了,及時跳出 } } } if(res!=flow)lev[u]=-1;//沒流完,說明以後不能從這個點流出任何流量,那就不需要這個點了 return res; } int main(){ int n=read(); int k=read(); int m=n*2+2; memset(head,-1,sizeof(head)); for(int i=1;i<=k;i++){ int s=read()+1; int e=read()+n+1; add(s,e,1); add(e,s,0); } for(int i=1;i<=n;i++){ add(1,i+1,1); add(i+1,1,0); add(i+n+1,m,1); add(m,i+n+1,0); } int ans=0; while(bfs(m)==1)ans+=dinic(1,INF,m); printf("%d\n",ans); return 0; }

POJ3041:Asteroids——題解