5874:Social Holidaying
問題文
https://icpcarchive.ecs.baylor.edu/external/58/5874.pdf
二部グラフのマッチング。
嘘解法だった。本当は一般グラフのマッチングで解くらしい。
#include<iostream> #include<vector> #include<algorithm> #include<set> #define INF 1LL<<62 #define MAX_V 1000 using namespace std; typedef long long ll; struct edge{ll to,cap,rev;}; vector<edge>G[MAX_V]; bool used[MAX_V]; 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}); } ll dfs(ll v,ll t,ll 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){ ll 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; } ll max_flow(int s,int t){ ll flow=0; for(;;){ fill(used,used+MAX_V,false); ll f=dfs(s,t,INF); if(f==0)return flow; flow+=f; } } int main(void){ int tc; cin >> tc; while(tc--){ for(int i=0;i<MAX_V;i++)G[i].clear(); int n,m; cin >> n >> m; vector<int>v(n); for(int i=0;i<n;i++)cin >> v[i]; set<int>S; for(int i=0;i<m;i++){ int a; cin >> a; S.insert(a); } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(i==j)continue; if(S.count(v[i]+v[j]))add_edge(i,j+n,1); } } for(int i=0;i<n;i++)add_edge(2*n,i,1); for(int i=0;i<n;i++)add_edge(i+n,2*n+1,1); cout << max_flow(2*n,2*n+1)/2 << endl; } return 0; }