我突然很怀念USACO,去年我A的差不多了就不想A了。。这个月把它A完吧(*^__^*)
这个题目大意nocow上有。。不过我的算法完全是错的居然过了囧。。
很明显是一个最小割的问题,关键是要让字典序最小,
一般来说是要一个个边枚举的删过去的,但是我懒得怎么搞,于是我给每个节点的点权改成了10000+i i表示第i个节点,然后就这样做了。。
结果居然AC了。这数据也太烂了囧。。
Code:
/* PROG: telecow LANG: C++ ID: Tom Chen*/#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<vector>#include<set>#include<queue>#include<map>#define rep(i,n) for(int i=0;i<n;i++)#define For(i,a,b) for(int i=a;i<=b;i++)#define tr(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define all(x) x.begin(),x.end()#define pb push_backusing namespace std;const int inf=~0U>>1,maxn=200+10;typedef vector<int> vi;struct Edge{ int t,c; Edge*next,*op; Edge(int _t,int _c,Edge* _next):t(_t),c(_c),next(_next){}}*E[maxn]={0};void InsEdge(int s,int t,int c){ E[s]=new Edge(t,c,E[s]); E[t]=new Edge(s,0,E[t]); E[s]->op=E[t];E[t]->op=E[s];}int vs,vt,n,m;int h[maxn],vh[maxn];const int in=0,out=1,off=10000;inline int node(int x,int type){ return x*2+type;}void Init(){ cin>>n>>m>>vs>>vt;vs–;vt–; vs=node(vs,out); vt=node(vt,in); int s,t; rep(i,n) InsEdge(node(i,in),node(i,out),off+i); while(m–) { cin>>s>>t;–s;–t; InsEdge(node(s,out),node(t,in),inf); InsEdge(node(t,out),node(s,in),inf); }}int v;int aug(int no,int m){ if(no==vt) return m; int l=m; for(Edge*i=E[no];i;i=i->next)if(i->c&&h[no]==h[i->t]+1) { int d=aug(i->t,min(l,i->c)); i->c-=d,i->op->c+=d,l-=d; if(!l||h[vs]>=v) return m-l; } int minh=v; for(Edge*i=E[no];i;i=i->next)if(i->c) minh=min(minh,h[i->t]+1); if(!–vh[h[no]]) h[vs]=v;++vh[h[no]=minh]; return m-l;}int CalFlow(){ memset(h,0,sizeof(h)); memset(vh,0,sizeof(vh)); v=n*2;vh[0]=v;int flow=0; while(h[vs]<v) flow+=aug(vs,inf); return flow;}bool Vis[maxn]={0};void dfs(int x){ Vis[x]=true; for(Edge*i=E[x];i;i=i->next)if(i->c&&!Vis[i->t])dfs(i->t);}bool Used(int x){ if (Vis[node(x,in)]&&!Vis[node(x,out)]) return true; return false;}void Work(){ int flow=CalFlow()/off; cout<<flow<<endl; vi Ans; dfs(vs); rep(i,n)if(Used(i)) Ans.pb(i+1); cout<<Ans[0]; for(int i=1;i<Ans.size();i++) cout<<" "<<Ans[i]; cout<<endl;}int main(){ freopen("telecow.in","r",stdin); freopen("telecow.out","w",stdout); Init(); Work();}