主要想补24题。
这是部落冲突那道题的妈
由于路径不可覆盖
顾考虑拆点。
但是还是学习了一下怎么记录路径
由于流量为1
所以直接把1的流量用掉的时候路径必然是这一条
然后处理一个next数组
递归打印
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=10000;
struct Front_star{
int u,v,w,nxt;
}e[N*4];
int cnt=1;
int first[N]={};
void addedge(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void add(int u,int v,int w){
addedge(u,v,w);
addedge(v,u,0);
}
int S=0,T;
int n,m;
queue<int> Q;
int d[N]={};
int s[N]={};
int t[N]={};
int vis[N]={};
bool BFS(){
Q.push(S);
memset(d,-1,sizeof(d));
d[S]=1;
while(!Q.empty()){
int x=Q.front();
Q.pop();
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w&&d[v]==-1){
d[v]=d[x]+1;
Q.push(v);
}
}
}
return d[T]!=-1;
}
int DFS(int st,int ed,int nowdat){
int dat=0;
if(st==ed)return nowdat;
for(int i=first[st];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w&&d[v]==d[st]+1){
int now=min(e[i].w,nowdat-dat);
now=DFS(v,ed,now);
dat+=now;
e[i].w-=now;
e[i^1].w+=now;
if(now!=0&&st!=S&&v!=T){
s[st]=v-n;
t[v-n]=st;
}
}
}
if(!dat)d[st]=-2;
return dat;
}
void dfs(int x){
if(x==0)return;
// cout<<s[x]<<'\n';
cout<<x<<" ";
if(s[x]!=x)dfs(s[x]);
vis[x]=1;
}
void MCMF(){
int ret=0;
while(BFS()){
ret+=DFS(S,T,INF);
}
for(int i=1;i<=n;i++){
if(!vis[i]){
dfs(i);cout<<'\n';
}
}
cout<<n-ret;
}
int main(){
read(n);
read(m);
T=2*n+1;
for(int i=1;i<=m;i++){
int u,v;
read(u);
read(v);
add(u,v+n,1);
}
for(int i=1;i<=n;i++){
add(S,i,1);
add(i+n,T,1);
}
MCMF();
return 0;
}