[網路流24題-12]最小路徑覆蓋問題
阿新 • • 發佈:2018-12-10
最小路徑覆蓋問題
有點蠢。。。結論題。。。(還是魔術球問題的一個部分)
DAG最小路徑覆蓋直接拆點建二分圖然後頂點數-最大匹配就可以了。。。
其他相關結論見魔術球問題(大霧)
大體相當於“找出路”。
蠢蠢的還RE了一發QAQ
附程式碼。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #define inf 20021225 #define ll long long using namespace std; struct edge{int to,lt,f;}e[20000]; int in[400],cnt=1,s,t,dep[400],n,m; queue<int> que; void add(int x,int y,int f) { e[++cnt].to=y;e[cnt].lt=in[x];e[cnt].f=f;in[x]=cnt; e[++cnt].to=x;e[cnt].lt=in[y];e[cnt].f=0;in[y]=cnt; } bool bfs() { while(!que.empty()) que.pop(); memset(dep,0,sizeof(dep)); dep[s]=1;que.push(s); while(!que.empty()) { int x=que.front();que.pop(); for(int i=in[x];i;i=e[i].lt) { int y=e[i].to; if(!dep[y]&&e[i].f) { dep[y]=dep[x]+1; if(y==t) return 1; que.push(y); } } } return 0; } int nxt[600]; int dfs(int x,int flow) { if(x==t||!flow) return flow; int cur=flow; for(int i=in[x];i;i=e[i].lt) { int y=e[i].to; if(dep[y]==dep[x]+1&&e[i].f) { int tmp=dfs(y,min(e[i].f,cur)); if(tmp) nxt[x]=y-n; cur-=tmp;e[i].f-=tmp;e[i^1].f+=tmp; if(!cur) return flow; } } dep[x]=-1;return flow-cur; } int dinic() { int ans=0; while(bfs()) ans+=dfs(s,inf); return ans; } bool vis[600]; int main() { int x,y; scanf("%d%d",&n,&m); s=2*n+1;t=s+1; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); add(x,y+n,1); } for(int i=1;i<=n;i++) add(s,i,1),add(i+n,t,1); dinic();int ans=0; for(int i=1;i<=n;i++) { if(!vis[i]) { while(i&&i!=t-n) { printf("%d ",i); vis[i]=1;i=nxt[i]; } printf("\n"); ans++; } } printf("%d\n",ans); return 0; }