2021.11.02 二分图

[P1963 NOI2009] 变换序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// https://www.luogu.com.cn/blog/colazcy/solution-p1963
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

const int N=21000;
int n,vis[N],link[N],ans[N];
vector<int>a[N];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline int dfs(int x){
	for(int i=0;i<(int)a[x].size();i++){
		int v=a[x][i];
		if(vis[v])continue;
		vis[v]=1;
		if(link[v]==-1||dfs(link[v])){
			link[v]=x;
			ans[x]=v;
			return 1;
		}
	}
	return 0;
}
inline int xiongyali(){
	int ans=0;
	memset(link,-1,sizeof(link));
	for(int i=n-1;i>=0;i--){
		memset(vis,0,sizeof(vis));
		if(dfs(i))++ans;
	}
	return ans;
}

int main(){
	n=read();
	for(int i=0;i<n;i++){
		int x=read();
		if(i-x>=0)a[i].push_back(i-x);
		if(i+x<n)a[i].push_back(i+x);
		if(i-x+n<n)a[i].push_back(i-x+n);
		if(i+x-n>=0)a[i].push_back(i+x-n);
	}
	for(int i=0;i<n;i++)sort(a[i].begin(),a[i].end());
	int fin=xiongyali();
	if(fin!=n)return puts("No Answer"),0;
	for(int i=0;i<n;i++)cout<<ans[i]<<" ";cout<<endl;
	return 0;
}

[P7368 USACO05NOV]Asteroids G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=510;
int n,m,a[N][N],link[N],vis[N];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline int dfs(int x){
	for(int i=1;i<=n;i++){
		if(i==x||!a[x][i])continue;
		if(vis[i])continue;
		vis[i]=1;
		if(!link[i]||dfs(link[i]))return link[i]=x,1;
	}
	return 0;
} 
inline int xiongyali(){
	int ans=0;
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof(vis));
		if(dfs(i))++ans;
	}
	return ans;
}

int main(){
	n=read();m=read();
	for(int i=1;i<=m;i++){
		int u,v;
		u=read();v=read();
		a[u][v]=1;
	}
	cout<<xiongyali();
	return 0;
}

[P1894 USACO4.2]完美的牛栏The Perfect Stall - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=210;
int n,m,a[N][N],link[N],vis[N];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline int dfs(int x){
	for(int i=1;i<=m;i++){
		if(!a[x][i])continue;
		if(vis[i])continue;
		vis[i]=1;
		if(!link[i]||dfs(link[i]))return link[i]=x,1;
	}
	return 0;
}
inline int xiongyali(){
	int ans=0;
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof(vis));
		if(dfs(i))++ans;
	}
	return ans;
}

int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		int x=read();
		for(int j=1;j<=x;j++){
			int u=read();
			a[i][u]=1;
		}
	}
	cout<<xiongyali();
	return 0;
}

最佳匹配

P1559 运动员最佳匹配问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

不会KM,直接上EK~

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const int N=45;
const int inf=0x3f3f3f3f;
int n,F[N][N],M[N][N],cnt=1,head[N],dis[N],pre[N],flow[N],vis[N];
int maxnflow,maxncost,start,endi;
struct node{
	int to,next,val,cost;
}a[6010];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline void addi(int u,int v,int w,int x){
	++cnt;
	a[cnt].to=v;
	a[cnt].val=w;
	a[cnt].cost=x;
	a[cnt].next=head[u];
	head[u]=cnt;
}
inline void add(int u,int v,int w,int x){
	addi(u,v,w,x);addi(v,u,0,-x);
}
inline int spfa(int s,int t){
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int>q;
	q.push(s);
	dis[s]=0;vis[s]=1;flow[s]=inf;
	while(!q.empty()){
		int x=q.front();q.pop();
		vis[x]=0;
		for(int i=head[x];i;i=a[i].next){
			int v=a[i].to;
			if(dis[v]>dis[x]+a[i].cost&&a[i].val>0){
				dis[v]=dis[x]+a[i].cost;
				flow[v]=min(flow[x],a[i].val);
				pre[v]=i;
				if(!vis[v])vis[v]=1,q.push(v);
			}
		}
	}
	return dis[t]!=inf;
}
inline void update(int s,int t){
	int x=t;
	while(x!=s){
		int xi=pre[x];
		a[xi].val-=flow[t];
		a[xi^1].val+=flow[t];
		x=a[xi^1].to;
	}
	maxnflow+=flow[t];
	maxncost+=flow[t]*dis[t];
}
inline void ek(int s,int t){
	while(spfa(s,t))update(s,t);
}

int main(){
	n=read();
	start=0,endi=n*2+1;
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)F[i][j]=read();
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)M[i][j]=read();
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)add(i,j+n,1,-F[i][j]*M[j][i]);
	for(int i=1;i<=n;i++)add(start,i,1,0),add(i+n,endi,1,0);
	ek(start,endi);
	cout<<-maxncost;
	return 0;
}

[P2457 SDOI2006]仓库管理员的烦恼 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const int M=5e4+10;
const int N=200;
const int K=N*2;
const int inf=0x3f3f3f3f;
int n,val[N][N],sum[N],cnt=1,head[K],dis[K],vis[K],flow[K],pre[K];
int maxncost,maxnflow,S,T;
struct node{
	int to,next,val,cost;
}a[M];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline void addi(int u,int v,int w,int x){
	++cnt;
	a[cnt].to=v;
	a[cnt].val=w;
	a[cnt].cost=x;
	a[cnt].next=head[u];
	head[u]=cnt;
}
inline void add(int u,int v,int w,int x){
	addi(u,v,w,x);addi(v,u,0,-x);
}
inline int spfa(int s,int t){
	queue<int>q;
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;flow[s]=inf;vis[s]=1;
	q.push(s);
	while(!q.empty()){
		int x=q.front();q.pop();
		vis[x]=0;
		for(int i=head[x];i;i=a[i].next){
			int v=a[i].to;
			if(dis[v]>dis[x]+a[i].cost&&a[i].val){
				dis[v]=dis[x]+a[i].cost;
				flow[v]=min(flow[x],a[i].val);
				pre[v]=i;
				if(!vis[v])vis[v]=1,q.push(v);
			}
		}
	}
	return dis[t]!=inf;
}
inline void update(int s,int t){
	int x=t;
	while(x!=s){
		int xi=pre[x];
		a[xi].val-=flow[t];
		a[xi^1].val+=flow[t];
		x=a[xi^1].to;
	}
	maxnflow+=flow[t];
	maxncost+=flow[t]*dis[t];
}
inline void ek(int s,int t){
	while(spfa(s,t))update(s,t);
}

int main(){
	n=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			val[i][j]=read();
			sum[j]+=val[i][j];
		}
	}
	S=n*2+1,T=n*2+2;
	for(int i=1;i<=n;i++){
		add(S,i,1,0);add(i+n,T,1,0);
		for(int j=1;j<=n;j++)
		add(i,j+n,1<<30,sum[i]-val[j][i]);
	}
	ek(S,T);
	cout<<maxncost;
	return 0;
}

难题

[P6185 NOI Online #1 提高组] 序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

#define int long long
const int N=6e5+10;
typedef long long ll;
ll sum,val[N];
int t,n,m,flag,e[N],b[N],fa[N],cnt,head[N],col[N];
struct node{
	int to,next;
}a[N*2];
struct nodei{
	int flag,x,y;
}op[N*2];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline void add(int u,int v){
	++cnt;
	a[cnt].to=v;
	a[cnt].next=head[u];
	head[u]=cnt;
}
inline int find(int x){
	return fa[x]==x?fa[x]:fa[x]=find(fa[x]); 
}
inline void merge(int x,int y){
	int xi=find(x),yi=find(y);
	if(xi==yi)return ;
	fa[xi]=yi;
	val[yi]+=val[xi];
}
inline void dfs(int x,int coli){
	col[x]=coli;
	if(coli)sum+=val[x];
	else sum-=val[x];
	for(int i=head[x];i;i=a[i].next){
		int v=a[i].to;
		if(col[v]==-1)dfs(v,coli^1);
		else if(col[v]==col[x])flag=1;
	}
}

signed main(){
	t=read();
	while(t--){
		memset(col,-1,sizeof(col));
		memset(head,0,sizeof(head));
		n=read();m=read();
		for(int i=1;i<=n;i++)e[i]=read();
		for(int i=1;i<=n;i++)b[i]=read(),fa[i]=i,val[i]=e[i]-b[i];
		for(int i=1;i<=m;i++){
			op[i].flag=read();op[i].x=read();op[i].y=read();
			if(op[i].flag==2)merge(op[i].x,op[i].y);
		}
		for(int i=1;i<=m;i++)if(op[i].flag==1){
			int u=find(op[i].x),v=find(op[i].y);
			add(u,v);add(v,u);
		}
		int ans=1;
		for(int i=1;i<=n;i++){
			if(find(i)==i&&col[i]==-1){
				sum=flag=0;
				dfs(i,0);
				for(int j=head[i];j;j=a[j].next){
					int v=a[j].to;
					if(v==i){
						flag=1;
						break;
					}
				}
				if(head[i]==0)ans&=sum==0?1:0;
				else if(flag==1)ans&=sum%2==0?1:0;
				else ans&=sum==0?1:0;
			}
		}
		if(ans)puts("YES");
		else puts("NO");
	}
	return 0;
}

[P3033 USACO11NOV]Cow Steeplechase G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

注意:cnt在网络流里要从1开始

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

#define int long long
const int N=260;
int n,cnt=1,head[N],dis[N],dep[N],cur[N];
int S,T,topx,topy;
struct nodex{
	int id,y1,y2,x;
	bool operator <(const nodex &b)const{
		return x<b.x;
	}
}linex[N];
struct nodey{
	int id,x1,x2,y;
	bool operator <(const nodey &b)const{
		return x1==b.x1?x2<b.x2:x1<b.x1;
	}
}liney[N];
struct node{
	int to,next,val;
}a[N*N*10];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
inline void addi(int u,int v,int w){
	++cnt;
	a[cnt].to=v;
	a[cnt].val=w;
	a[cnt].next=head[u];
	head[u]=cnt;
}
inline void add(int u,int v,int w){
	addi(u,v,w);addi(v,u,0);
}
inline int bfs(int s,int t){
	queue<int>q;
	memset(dep,0,sizeof(dep));
	memcpy(cur,head,sizeof(head));
	dep[s]=1;
	q.push(s);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=head[x];i;i=a[i].next){
			int v=a[i].to;
			if(!dep[v]&&a[i].val)dep[v]=dep[x]+1,q.push(v);
		}
	}
	return dep[t];
}
inline int dfs(int x,int t,int f){
	if(x==t)return f;
	int ans=0;
	for(int i=cur[x];i&&ans<f;i=a[i].next){
		int v=a[i].to,fi=0;
		cur[x]=i;
		if(dep[v]==dep[x]+1&&a[i].val&&(fi=dfs(v,t,min(a[i].val,f-ans)))>0)
		a[i].val-=fi,a[i^1].val+=fi,ans+=fi;
	}
	return ans;
}
inline int dinic(int s,int t){
	int flow=0;
	while(bfs(s,t)){
		int x=0;
		if((x=dfs(s,t,1<<30))>0)flow+=x;
	}
	return flow;
}

signed main(){
	n=read();
	S=n+1,T=n+2;
	for(int i=1;i<=n;i++){
		int x,y,u,v;
		x=read();y=read();u=read();v=read();
		if(x==u){
			++topx;
			linex[topx].x=x,linex[topx].id=i;
			linex[topx].y1=min(y,v),linex[topx].y2=max(y,v);
			add(i,T,1);
		}
		else if(y==v){
			++topy;
			liney[topy].y=y,liney[topy].id=i;
			liney[topy].x1=min(x,u),liney[topy].x2=max(x,u);
			add(S,i,1);
		}
	}
	sort(linex+1,linex+topx+1);
	sort(liney+1,liney+topy+1);
	int aimx=0,aimy=0;
	aimx=0;
	for(int i=1;i<=topy;i++){
		for(int j=1;j<=topx;j++){
			if(linex[j].x>=liney[i].x1&&linex[j].x<=liney[i].x2&&liney[i].y>=linex[j].y1&&liney[i].y<=linex[j].y2)
			add(liney[i].id,linex[j].id,1<<30);//,cout<<liney[i].id<<" "<<linex[j].id<<endl; 
		}
	}
	cout<<n-dinic(S,T);
	return 0;
}
 posted on 2021-11-03 16:08  eleveni  阅读(32)  评论(0)    收藏  举报