PKU 3041 Asteroids
åé¡æâ 3041 -- Asteroids
N*Nã®æ ¼åä¸ã«Kåã®å°ææãããã¾ããå°ææiã®ä½ç½®ã¯(R[i],C[i])ã«ããã¾ãã縦ã¾ãã¯æ¨ªä¸ç´ç·ä¸ã®å°ææããã¹ã¦ä¸çºã®ãã¼ã ã§ç ´å£ã§ããå¼·åãªæ¦å¨ãããããããç¨ãã¦ãã¹ã¦ã®å°ææãç ´å£ããããã«å¿ è¦ãªæå°ã®çºå°åæ°ãæ±ããªããã
æ®éã«æ¢ç´¢ããã¨O(2^(2*n))ã¨ããããã
ãã¼ã ã®æã¡æ¹ã¯ç¸¦ã横2éããããªãã®ã§ãã¼ã ã®æã¡æ¹ãé ç¹ãããã«ãã£ã¦ç ´å£ã§ããææã辺ã¨ããäºé¨ãããã³ã°ã«å¸°çã§ãã(quote from è»æ¬)
ãããªè³¢ãããæ¹æãã¤ããªãã...
ã¨ãããã¨ã§åã®ããã¼åé¡ã
ä»åã¯äºé¨ãããã³ã°ã®æå°ç¹ã«ãã¼åé¡ãªã®ã§ãFold-Fulkersonã§æ®éã«æ大ãããã³ã°ãæ±ããã
ã¡ãªã¿ã«æ大ãããã³ã°ã¯ãäºãã«ç«¯ç¹ãå
±æããªã辺éåMâEãã®äºã
äºé¨ãããã³ã°ã®å ´åã¯ãããæå°ç¹ã«ãã¼ã«ããªãã
ã³ã¡ã³ãæ·»ããªããã³ã¼ãæ¸ãã¨é ã«å ¥ããããã§ããï¼
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<string> #include<cmath> #include<map> #include<cstdlib> #include<climits> #include<cstring> #include<queue> #include<deque> #include<set> #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define EPS 0.0001 using namespace std; typedef long long ll; const int MAX_V=1000000; struct edge{int to,cap,rev;}; //è¡ãå ã容éãé辺ã®ã¤ã³ããã¯ã¹ vector<edge>G[MAX_V];//é£æ¥ãªã¹ã bool used[MAX_V];//éè·¯ç¢ºèª //fromããtoã¸å®¹écapã®è¾ºã追å (éå¤ã容é0ã§è¿½å ) void add_edge(int from,int to,int cap){ G[from].push_back((edge){to,cap,G[to].size()}); G[to].push_back((edge){from,0,G[from].size()-1}); } //æ·±ãåªå ã§ã辺ã«æµããã ãæµã(éè·¯ãªã) int dfs(int v,int t,int f){ if(v==t) return f; used[v]=true;//éè·¯é²æ¢ for(int i=0;i<G[v].size();i++){ edge &e=G[v][i]; if(!used[e.to] && e.cap>0){ int d=dfs(e.to,t,min(f,e.cap)); if(d>0){//容éã足ãããæµããäºã«ãã e.cap-=d; G[e.to][e.rev].cap+=d;//æåç·åä¸ãæµããã®ã§é辺ã追å ãã return d; } } } return 0; //æµããªã } const int INF=1<<30; int max_flow(int s,int t){ int flow=0; //éè·¯ãªãã§æµããã ãæµãã¨ããä½æ¥ãç¹°ãè¿ã //æµãããé辺ã追å ããã®ã§ãæ®ä½ãã¹ãå¢ãã¦ããå¯è½æ§ããã for(;;){ memset(used,0,sizeof(used)); int f=dfs(s,t,INF); if(f==0) return flow; flow+=f; } return 0; } int R[MAX_V],C[MAX_V]; int N,K; //äºé¨ãããã³ã° int Matching(){ int s=N+N+1,t=s+1; for(int i=0;i<N;i++) add_edge(s,i,1); for(int i=0;i<N;i++) add_edge(N+i,t,1); for(int i=0;i<K;i++) add_edge(R[i]-1,N+C[i]-1,1); return max_flow(s,t); } int main(){ cin>>N>>K; REP(i,K) cin>>R[i]>>C[i]; cout<<Matching()<<endl; }