题目:https://www.luogu.org/problemnew/show/P1344
就是求最小割;
但是还要边数最小,所以把边权都*1001+1,这样原来流量部分是*1001,最大流一样的不影响,而+1会使其尽量减少边数;
bfs 里忘了给 dis[] 赋0了调了好半天...尴尬...
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef long long ll; int const xn=35,xm=1005; int n,m,hd[xn],ct=1,to[xm<<1],nxt[xm<<1],dis[xn],cur[xn]; ll ans,c[xm<<1],inf=1e12; queue<int>q; void add(int x,int y,ll cc) {to[++ct]=y; nxt[ct]=hd[x]; c[ct]=cc; hd[x]=ct;} int rd() { int ret=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();} while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return f?ret:-ret; } bool bfs() { while(q.size())q.pop(); memset(dis,0,sizeof dis);// dis[1]=1; q.push(1); while(q.size()) { int x=q.front(); q.pop(); for(int i=hd[x],u;i;i=nxt[i]) if(!dis[u=to[i]]&&c[i])dis[u]=dis[x]+1,q.push(u); } return dis[n]; } ll dfs(int x,ll fl) { if(x==n)return fl; ll ret=0; for(int &i=cur[x],u;i;i=nxt[i]) { if(dis[u=to[i]]!=dis[x]+1||!c[i])continue; ll tmp=dfs(u,min(fl-ret,c[i])); if(!tmp)dis[u]=0;// c[i]-=tmp; c[i^1]+=tmp; ret+=tmp; if(ret==fl)return ret;// } return ret; } int main() { n=rd(); m=rd(); for(int i=1,x,y;i<=m;i++) { ll z; x=rd(); y=rd(); z=rd(); z=z*1001+1; add(x,y,z); add(y,x,0); } while(bfs()) { memcpy(cur,hd,sizeof hd); ans+=dfs(1,inf); } printf("%lld %lld ",ans/1001,ans%1001); return 0; }