【模板】网络最大流题解

题目描述

对于一个 0∼n−1 的排列 p 和一个 x∈[0,n−1],每次操作时会依次发生以下两个事件:

  • x:=px​;
  • ∀i∈[0,n−1],pi​:=(pi​+1)modn。

称第 i 次操作后的 x 为 xi​,特别的,初始的 x 称为 x0​。

现在我们有 x0​=0,请你构造一个长度为 n 的排列 p 满足在 n−1 次操作后,∀i∈[0,n−1],∃j∈[0,n−1],xj​=i,即 x 是一个排列。

可以证明一定有解。

输入格式

一个正整数,表示 n。

输出格式

输出一行 n 个数,表示你构造的排列 p。

输入输出样例

输入 #1复制

4

输出 #1复制

2 1 0 3

说明/提示

样例解释

初始时,x=0,p=[2,1,0,3]。

第一次操作后,x=2,p=[3,2,1,0]。

第二次操作后,x=1,p=[0,3,2,1]。

第三次操作后,x=3,p=[1,0,3,2]。

数据范围

对于 30% 的数据,保证 n 为奇数。

对于 100% 的数据,保证 1≤n≤106。

思路

模板题,直接做即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,m,s,t,u,vv,w,he[500005],d[500005],no[500005],lk=0,cd=0,lof=1e18+7;
struct one{
    long long a,b;
	long long c,x;
}e[500005];
long long db=1;
vector<long long> v[2005];
queue<one> q;
void ad(long long u1,long long v1,long long w1){
    e[++db].a=u1;
    e[db].b=v1;
    e[db].c=w1;
    e[db].x=he[u1];
    he[u1]=db;
    e[++db].a=v1;
    e[db].b=u1;
    e[db].c=0;
    e[db].x=he[v1];
    he[v1]=db;
}
long long abcb(){
	for(int i=1;i<=n;i++){
		d[i]=lof;
	}
	queue<long long> q;
	q.push(s);
	d[s]=0;
	no[s]=he[s];
	while(q.size()!=0){
		long long a1=q.front();
		q.pop();
		for(int i=he[a1];i!=0;i=e[i].x){
			long long tt=e[i].b;
			if(e[i].c>=1&&d[tt]==lof){
				q.push(tt);
				no[tt]=he[tt];
				d[tt]=d[a1]+1;
				if(tt==t){
					return 1;
				} 
			}
		} 
	} 
	return 0;
}
long long abcd(long long a1,long long b1){
	if(a1==t){
		return b1;
	}
	long long df,kl=0;
	for(int i=no[a1];i!=0&&b1!=0;i=e[i].x){
		no[a1]=i;
		long long tt=e[i].b;
		if(e[i].c>=1&&d[tt]==d[a1]+1){
			df=abcd(tt,min(b1,e[i].c));
			if(df==0){
				d[tt]=lof;
			}
			e[i].c-=df;
			e[i^1].c+=df;
			kl+=df;
			b1-=df;
		}
	} 	
	return kl;
}
int main(){
    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++){
        cin>>u>>vv>>w;
        ad(u,vv,w);
    }
    while(abcb()!=0){
    	lk+=abcd(s,lof);
	}
    cout<<lk<<endl;
	return 0;
}

posted @ 2025-10-09 11:20  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源