ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kuangbin专题十 匹配问题专题(2020/11/22-2020/12/02) 19道

2020-12-27 12:02:11  阅读:183  来源: 互联网

标签:11 专题 int rep memset vis 2020 sizeof lin


专题链接kuangbin专题十 匹配问题

快速跳转

题目

HDU 1045 Fire Net
HDU 2444 The Accomodation of Students
HDU 1083 Courses
HDU 1281 棋盘游戏
HDU 2819 Swap
HDU 2389 Rain on your Parade
HDU 4185 Oil Skimming
POJ 3020 Antenna Placement
HDU 1054 Strategic Game
HDU 1151 Air Raid
POJ 2594 Treasure Exploration
HDU 3829 Cat VS Dog
POJ 2289 Jamie’s Contact Groups
POJ 2112 Optimal Milking
POJ 3189 Steady Cow Assignment
HDU 2255 奔小康赚大钱
HDU 3488 Tour
URAL 1099 Work Scheduling
HDU 4687 Boke and Tsukkomi

个人模板

匈牙利算法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define Ri(x) scanf("%d",&x)
#define Rii(x,y) scanf("%d%d",&x,&y)
#define ms0(ar) memset(ar,0,sizeof(ar))
#define ms1(ar) memset(ar,-1,sizeof(ar))
#define pb push_back
const int N=1e3,M=1e4;
int n,p,m,cnt,ans;
int a[N],b[N],fst[N],nxt[M],to[M],lin[N];
bool vis[N];
void add(int x,int y){
	to[++cnt]=y;
	nxt[cnt]=fst[x];
	fst[x]=cnt;
}
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	while(Rii(n,p)){
		Ri(m);
		rep(i,1,n)
			Ri(a[i]);
		rep(i,1,p)
			Ri(b[i]);
		ms0(lin),ms0(fst);
		ans=cnt=0;
		int u,v;
		rep(i,1,m){
			Rii(u,v);
			add(u,v);
		}
		rep(i,1,n){
			ms0(vis);
			if(dfs(a[i])) ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
} 

可匹配多个的匈牙利算法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define Ri(x) scanf("%d",&x)
#define Rii(x,y) scanf("%d%d",&x,&y)
#define ms0(ar) memset(ar,0,sizeof(ar))
#define ms1(ar) memset(ar,-1,sizeof(ar))
#define pb push_back
const int N=1e3,M=1e4;
int n,p,m,cnt,ans,d;
int a[N],b[N],fst[N],nxt[M],to[M],c[N],lin[N][N];
bool vis[N];
void add(int x,int y){
	to[++cnt]=y;
	nxt[cnt]=fst[x];
	fst[x]=cnt;
}
bool dfs(int x,int d){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(lin[v][0]<d){
				lin[v][++lin[v][0]]=x;
				return 1;
			}
			else 
				rep(j,1,lin[v][0])
					if(dfs(lin[v][j],d)){
						lin[v][j]=x;
						return 1;
					}
		}
	}
	return 0;
}
int main(){
	while(Rii(n,p)){
		Ri(m);
		Ri(d);
		rep(i,1,n)
			Ri(a[i]);
		rep(i,1,p)
			Ri(b[i]);
		ms0(lin),ms0(fst);
		ans=cnt=0;
		int u,v;
		rep(i,1,m){
			Rii(u,v);
			add(u,v);
		}
		rep(i,1,n){
			ms0(vis);
			if(dfs(a[i],d)) ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
} 

KM算法

#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
#define Ri(x) scanf("%d",&x)
#define Rii(x) scanf("%d%d",&x,&y)
const int N=1e3,INF=0x3f3f3f3f;
int g[N][N],gap[N],exl[N],exr[N],lin[N],n;
bool visl[N],visr[N];
bool dfs(int x){
	visl[x]=1;
	rep(i,1,n){
		if(visr[i]) continue;
		int d=exl[x]+exr[i]-g[x][i];
		if(!d){
			visr[i]=1;
			if(!lin[i]||dfs(lin[i])){
				lin[i]=x;
				return 1;
			}
		}
		else if(gap[i]>d) gap[i]=d;
	}
	return 0;
} 
int main(){
	while(Ri(n)){
		ms0(lin);
		rep(i,1,n)
			rep(j,1,n){
				Ri(g[i][j]);
				exl[i]=max(exl[i],g[i][j]);
			}
		rep(i,1,n){
			rep(j,1,n) gap[j]=INF;
			while(1){
				ms0(visl),ms0(visr);
				if(dfs(i)) break;
				int d=INF;
				rep(j,1,n)
					if(!visr[j]) d=min(d,gap[j]);
				rep(j,1,n){
					if(visl[j]) exl[j]-=d;
					if(visr[j]) exr[j]+=d;
					else gap[j]-=d;
				}
			}
		}
		int ans=0;
		rep(i,1,n) ans+=g[lin[i]][i];
		printf("%d\n",ans);
	}
	return 0;
} 

AC代码

Fire Net

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
int n,cnt,a[5][5],b[5][5],line[105],ans,c1,c2;
char p[5][5];
bool vis[105],maps[105][105];
bool dfs(int x){
	rep(i,1,c2)
		if(maps[x][i]&&!vis[i]){
			vis[i]=1;
			if((!line[i])||dfs(line[i])){
				line[i]=x;
				return 1;
			}
		}
	return 0;
}
int main(){
	while(cin>>n){
		if(!n) break;
		cnt=1,ans=0;
		memset(maps,0,sizeof(maps));
		memset(line,0,sizeof(line));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		rep(i,1,n){
			rep(j,1,n){
				cin>>p[i][j];
				if(p[i][j]=='.') a[i][j]=cnt;
				else cnt++; 
			}
			cnt++;
		}
		c1=cnt;
		cnt=1;
		rep(i,1,n){
			rep(j,1,n)
				if(p[j][i]=='.') b[j][i]=cnt,maps[a[j][i]][b[j][i]]=1;
				else cnt++;
			cnt++;
		}
		c2=cnt;
		rep(i,1,100){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
} 

The Accomodation of Students

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int N=500+5,M=2*N*N; 
int n,m,fst[N],nxt[M],line[N],to[M],cnt=0,c[N];
bool vis[N];
void add(int x,int y){
	nxt[++cnt]=fst[x];
	fst[x]=cnt;
	to[cnt]=y;
}
bool xyl(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if((!line[v])||xyl(line[v])){
				line[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
bool rs(int x,int co){
	c[x]=co;
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!c[v]){
			if(!rs(v,-co)) return 0; 
		}
		else if(c[v]==co) return 0;
	}
	return 1;
}
bool eft(){
	rep(i,1,n)
		if(!c[i])
			if(!rs(i,1)) return 0;
	return 1;
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		memset(c,0,sizeof(c));
		memset(fst,0,sizeof(fst));
		memset(nxt,0,sizeof(nxt));
		memset(line,0,sizeof(line));
		int u,v;
		cnt=0;
		rep(i,1,m){
			cin>>u>>v;
			add(u,v);
			add(v,u);
		}
		bool flag=1;
		int ans=0;
		if(!eft()) flag=0;	
		if(flag){
			rep(i,1,n){
				memset(vis,0,sizeof(vis));
				if(c[i]==1&&xyl(i)) ans++;
			}
			cout<<ans<<endl;
		}
		else cout<<"No"<<endl; 
	}
	return 0;
}

Courses

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int P=100+5,N=300+5;
int p,n,fst[P],to[P*N],line[N],nxt[P*N],sum=0;
void add(int x,int y){
	nxt[++sum]=fst[x];
	fst[x]=sum;
	to[sum]=y;
}
bool vis[N];
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int s=to[i];
		if(!vis[s]){
			vis[s]=1;
			if(!line[s]||dfs(line[s])){
				line[s]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int question,cnt,stu;
	cin>>question;
	while(question--){
		cin>>p>>n;
		sum=0;
		memset(fst,0,sizeof(fst));
		memset(nxt,0,sizeof(nxt));
		memset(line,0,sizeof(line));
		rep(i,1,p){
			cin>>cnt;
			rep(j,1,cnt){
				cin>>stu;
				add(i,stu);
			}
		}
		int ans=0;
		rep(i,1,p){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) ans++;
		}
		if(ans==p) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

棋盘游戏

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int N=105,K=N*N;
int n,m,k,line[N];
bool maps[N][N],vis[N];
bool dfs(int x){
	rep(i,1,m)
		if(maps[x][i]&&!vis[i]){
			vis[i]=1;
			if(!line[i]||dfs(line[i])){
				line[i]=x;
				return 1;
			}
		}
	return 0;
}
int main(){
	int t=0;
	while(cin>>n>>m>>k){
		memset(maps,0,sizeof(maps));
		memset(line,0,sizeof(line));
		int u,v,ans=0;
		rep(i,1,k){
			cin>>u>>v;
			maps[u][v]=1;
		}
		int l=0,cnt=0;
		rep(i,1,n){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) ans++;
		}
		l=ans;
		rep(i,1,n)
			rep(j,1,m)
				if(maps[i][j]){
					maps[i][j]=ans=0;
					memset(line,0,sizeof(line));
					rep(p,1,n){
						memset(vis,0,sizeof(vis));
						if(dfs(p)) ans++;
					}
					maps[i][j]=1;
					if(ans!=l) cnt++;
				}
		cout<<"Board "<<++t<<" have "<<cnt<<" important blanks for "<<l<<" chessmen."<<endl; 
	}
	return 0;
}

Swap

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int N=105;
int a[N][N],n,fst[N],nxt[N*N],to[N],lin[N],e,cnt,tem,r[N];
struct op{
	int x,y;
}ans[N*N];
void add(int x,int y){
	to[++e]=y;
	nxt[e]=fst[x];
	fst[x]=e;
}
bool vis[N];
bool dfs(int x){
	rep(i,1,n)
		if(a[x][i]&&!vis[i]){
			vis[i]=1;
			if(!lin[i]||dfs(lin[i])){
				lin[i]=x;
				r[x]=i;
				return 1;
			}
		}
	return 0;
}
int main(){
	while(cin>>n){
		int temp;
//		memset(fst,0,sizeof(fst));
//		memset(nxt,0,sizeof(nxt));
		memset(lin,0,sizeof(lin)); 
		memset(r,0,sizeof(r));
		memset(ans,0,sizeof(ans));
		e=0;
		rep(i,1,n)
			rep(j,1,n){
				cin>>a[i][j];
//				if(a[i][j]) add(i,j);
			}
		cnt=tem=0;
		rep(i,1,n){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) tem++; 
			else break;
		} 
		if(tem<n) cout<<-1<<endl;
		else{
			rep(i,1,n)
				if(r[i]!=i)
					rep(j,(i+1),n)
						if(r[j]==i){
							ans[++cnt].x=i;
							ans[cnt].y=r[i];
							r[j]=r[i];
							break;
						}
			cout<<cnt<<endl;
			rep(i,1,cnt) cout<<"C "<<ans[i].x<<" "<<ans[i].y<<endl;  
		}
	}
	return 0;
}

Rain on your Parade

#include <cstdio>
#include <cstring>
#include <cmath> 
#include <queue>
using namespace std;
const int N = 3e3 + 5, M = N * N, INF = 0x3f3f3f3f;
struct E {
	int v, next;
} e[M];
struct Node {
	double x, y, s;
} a[N], b[N];
int n, m, k, t, len, dis, h[N], mx[N], my[N], dx[N], dy[N];
bool vis[N]; 
void add(int u, int v) {
	e[++len].v = v;
	e[len].next = h[u];
	h[u] = len;
}
bool bfs() {
	queue<int> q;
	memset(dx, -1, sizeof(dx));
	memset(dy, -1, sizeof(dy));
	//找出未匹配的点 (左边)
	for (int i = 1; i <= n; i++) {
		if (mx[i] == -1) q.push(i), dx[i] = 0;
	}	
	dis = INF; //初始令增广路为无穷 
	while (!q.empty()) {
		int u = q.front(); q.pop();
		if (dx[u] > dis) break; //代表还有比dis更长的增广路 留待下次bfs扩展
		for (int j = h[u]; j; j = e[j].next) {
			int v = e[j].v; 
			if (dy[v] == -1) { //代表还未遍历过 
				dy[v] = dx[u] + 1; //给予层次
				if (my[v] == -1) {
					dis = dy[v]; //找到增广路 
				} else {
					//如果已经匹配了 就把匹配好的点(左边)放入队列进行扩展 
					dx[my[v]] = dy[v] + 1;
					q.push(my[v]);
				}
			}
		} 
	}
	return dis != INF; //等于INF就未找到增广路 
}
bool dfs(int u) {
	for (int j = h[u]; j; j = e[j].next) {
		int v = e[j].v;
		if (vis[v] || dy[v] != dx[u] + 1) continue; //如果未访问且是u的下层次点 
		vis[v] = true; 
		if (my[v] != -1 && dy[v] == dis) continue; //如果这个点已经匹配 且找到的增广路已经大于dis 
		if (my[v] == -1 || dfs(my[v])) {
			my[v] = u; mx[u] = v;
			return true;
		}
	}
	return false;
} 
int getMax() {
	int ans = 0;
	memset(mx, -1, sizeof(mx));
	memset(my, -1, sizeof(my));
	while (bfs()) { //查找是否有增广路 
		memset(vis, false, sizeof(vis)); //对于找到的一条增广路径查询 
		for (int i = 1; i <= n; i++) {
			if (mx[i] == -1 && dfs(i)) ans++; //如果未匹配才去dfs 
		} 		
	}
	return ans;
}
int main() {
	scanf("%d", &t);
	for (int T = 1; T <= t; T++) {
		memset(h, 0, sizeof(h)); len = 0;
		scanf("%d%d", &k, &n);
		for (int i = 1; i <= n; i++) {
			scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].s);
		}
		scanf("%d", &m);
		double x, y;
		for (int i = 1; i <= m; i++) {
			scanf("%lf%lf", &b[i].x, &b[i].y);  
		} 
		for (int i = 1; i <= m; i++) {
			x = b[i].x, y = b[i].y;	
			for (int j = 1; j <= n; j++) {
				double fx = a[j].x - x;
				double fy = a[j].y - y;
				double d = sqrt(fx*fx + fy*fy);
				if (d <= k * a[j].s) add(j, i);
			}
		}
		int ans=getMax();
		printf("Scenario #%d:\n%d\n\n", T, ans); 
	}	
	return 0;
}

Oil Skimming

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int N=1205;
int n,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0},a[N][N],fst[N*N],nxt[N*N*2],to[N*N*2],lin[N*N],cnt,ec;
bool vis[N*N];
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
bool dfs(int x){
	for(int i=fst[x];~i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(lin[v]==-1||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
char g[N][N];
int main(){
	int k,ans,cnt1,cnt2;
	char tem;
	cin>>k;
	rep(w,1,k){
		memset(fst,-1,sizeof(fst));
		memset(nxt,-1,sizeof(nxt));
		memset(lin,-1,sizeof(lin));
		memset(a,0,sizeof(a));
		cin>>n;
		cnt=ec=ans=0;
		rep(i,1,n)
			rep(j,1,n){
				cin>>g[i][j];
				if((i+j)&1&&g[i][j]=='#') a[i][j]=++cnt;
			}
		int t=cnt+1;
		rep(i,1,n)
			rep(j,1,n)
				if(g[i][j]=='#'&&!a[i][j]) a[i][j]=++cnt;
		ans=0;	
		rep(i,1,n)
			rep(j,1,n) 
				if((i+j)&1&&a[i][j])
					rep(p,0,3){
						int x=i+dx[p],y=j+dy[p];
						if(x<=n&&x>=1&&y<=n&&y>=1&&a[x][y]) add(a[i][j],a[x][y]);
					}
		rep(i,1,n*n){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) ans++;
		}
		cout<<"Case "<<w<<": "<<ans<<endl;
	}
	return 0;
}

Antenna Placement

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
const int H=45,W=15,P=H*W;
int a[H][W],dx[]={0,0,1,-1},dy[]={1,-1,0,0},fst[P>>1],nxt[P<<1],to[P<<1],lin[P>>1];
int ec,h,w;
bool vis[P>>1];
bool in(int x,int y){
	return x>=1&&x<=h&&y>=1&&y<=w;
}
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
void made(int x,int y){
	int tx,ty;
	rep(i,0,3){
		tx=x+dx[i],ty=y+dy[i];
		if(in(tx,ty)&&a[tx][ty]) add(a[x][y],a[tx][ty]);
	}
}
int main(){
	int t;
	cin>>t;
	while(t--){
		cin>>h>>w;
		char tem;
		int cnt1=0,cnt2=0,ans=0;
		memset(a,0,sizeof(a));
		memset(fst,0,sizeof(fst));
		memset(lin,0,sizeof(lin));
		ec=0;
		rep(i,1,h)
			rep(j,1,w){
				cin>>tem;
				if(tem=='*'){
					if((i+j)&1) a[i][j]=++cnt1;
					else a[i][j]=++cnt2;
				}
			}
		rep(i,1,h)
			rep(j,1,w)
				if((i+j)&1&&a[i][j])
					made(i,j);
		rep(i,1,cnt1){
			memset(vis,0,sizeof(vis));
			if(dfs(i)) ans++;
		}
		cout<<cnt1+cnt2-ans<<endl;
	}
	return 0;
}

Strategic Game

#include<iostream>
#include<cstring>
#include<string> 
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
//#define me0(ar) memset(ar,0,sizeof(ar))
//#define me1(ar) memset(ar,-1,sizeof(ar))
//#define pb push_back
const int N=1505,M=N*N;
int n,ec;
int fst[N],nxt[M],to[M],lin[N],c[N];
bool g[N][N],vis[N];
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
void rs(){
	int f[M]={0,0},head=0,tail=1;
	c[0]=1;
	do{
		head++;
		int u=f[head];
		if(vis[u]) continue;
		vis[u]=1;
		rep(i,0,n-1)
			if(g[u][i]){
				f[++tail]=i;
				c[i]=-c[u];
				if(c[u]==1) add(u,i);
			}
	}while(head<tail);
}
bool dfs(int x){
	for(int i=fst[x];~i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(lin[v]==-1||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int ans;
	while(cin>>n){
		memset(g,0,sizeof g);
		memset(lin,-1,sizeof lin);
		memset(fst,-1,sizeof fst);
		memset(nxt,-1,sizeof nxt);
		ans=ec=0;
		rep(i,1,n){
			string s;
			int nod=0,k=0,p=0,num;
			cin>>s;
			while(s[p]>='0'&&s[p]<='9') nod*=10,nod+=s[p++]-'0';
			p+=2;
			while(s[p]>='0'&&s[p]<='9') k*=10,k+=s[p++]-'0';
			rep(j,1,k){
				cin>>num;
				g[num][nod]=g[nod][num]=1;
			}
		}
		memset(vis,0,sizeof vis);
		rs();
		rep(i,0,n-1)
			if(c[i]==1){
				memset(vis,0,sizeof vis);
				if(dfs(i)) ans++;
			}
		cout<<ans<<endl;
	}
	return 0;
} 

Air Raid

#include<iostream>
#include<cstring>
#include<string> 
#include<vector>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof(ar))
#define me1(ar) memset(ar,-1,sizeof(ar))
#define pb push_back
const int N=245,M=N*N;
int n,k,ec;
int fst[N],nxt[M],to[M],lin[N];
void init(){
	ec=0;
	me0(fst);
	me0(nxt);
	me0(to);
	me0(lin);
}
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
bool vis[N];
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		init();
		cin>>n>>k;
		int sk,ek,ans=0;
		rep(i,1,k){
			cin>>sk>>ek;
			add(sk*2,ek*2-1);
		}
		rep(i,1,n){
			me0(vis);
			if(dfs(i*2)) ans++;
		}
		cout<<n-ans<<endl;
	}
	return 0;
}

Treasure Exploration

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof(ar))
#define me1(ar) memset(ar,-1,sizeof(ar))
const int N=505,M=5e3+5,MAXM=1e6;
int n,m,ec;
int fst[N<<1],nxt[MAXM],to[MAXM],lin[N<<1];
bool g[N][N],vis[N<<1];
void init(){
	ec=0;
	me0(g);
	me0(fst);
	me0(nxt);
	me0(to);
	me0(lin);
}
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	while(1){
		cin>>n>>m;
		init();
		if(!n) break;
		int u,v,ans=0;
		rep(i,1,m){
			cin>>u>>v;
			g[u][v]=1;
		}
		rep(i,1,n)
			rep(j,1,n)
				rep(k,1,n)
					if(g[i][k]&&g[k][j]) g[i][j]=1;
		rep(i,1,n)
			rep(j,1,n)
				if(g[i][j]) add(i*2,j*2-1);
		rep(i,1,n){
			me0(vis);
			if(dfs(i*2)) ans++;
		}
		cout<<n-ans<<endl;
	}
	return 0;
}

Cat VS Dog

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof(ar))
#define me1(ar) memset(ar,-1,sizeof(ar))
const int N=1005,M=1005,P=2005;
int n,m,p,ec;
int c1[P],c2[P],d1[P],d2[P],fst[N],nxt[P*P],to[P*P],lin[P];
void init(){
	ec=0;
	me0(c1),me0(c2),me0(d1),me0(d2),me0(fst),me0(nxt),me0(to),me0(lin);
}
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
bool vis[P];
bool dfs(int x){
	for(int i=fst[x];i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	while(cin>>n>>m>>p){
		int cntc=-1,cntd=0,ans=0,n1,n2;
		init();
		char a,b;
		rep(i,1,p){
			cin>>a>>n1>>b>>n2;
			if(a=='C') cntc+=2,c1[cntc]=n1,c2[cntc]=n2;
			else cntd+=2,d1[cntd]=n1,d2[cntd]=n2;
		}
		for(int i=1;i<=cntc;i+=2)
			for(int j=2;j<=cntd;j+=2)
				if(c2[i]==d1[j]||c1[i]==d2[j]) add(i,j);
		for(int i=1;i<=cntc;i+=2){
			me0(vis);
			if(dfs(i)) ans++;
		}
		cout<<p-ans<<endl;
	}
	return 0;
}

Jamie’s Contact Groups

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof(ar))
#define me1(ar) memset(ar,-1,sizeof(ar))
const int N=1e3+5,M=505,E=N*M;
int n,m,cnt,ec,tmp=0;
int fst[N],nxt[E],to[E],lin[M][N];
bool vis[N+M];
void init(){
	cnt=ec=0;
	me1(fst),me1(nxt);
	rep(i,0,m-1) lin[i][0]=0;
}
void add(int x,int y){
	to[++ec]=y;
	nxt[ec]=fst[x];
	fst[x]=ec;
}
bool dfs(int x,int d){
	for(int i=fst[x];~i;i=nxt[i]){
		int v=to[i];
		if(!vis[v]){
			vis[v]=1;
			if(lin[v][0]<d){
				lin[v][++lin[v][0]]=x;
				return 1;
			}
			else
				rep(i,1,lin[v][0])
					if(dfs(lin[v][i],d)){
						lin[v][i]=x;
						return 1;
					}
		}
	}
	return 0;
}
bool pd(int x){
	me0(lin);
	rep(i,1,n){
		me0(vis);
		if(!dfs(i,x)) return 0;
	}
	return 1;
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		if(!n) break;
		init();
		
		char s=getchar();
		rep(i,1,n){
			cnt++;
			bool flag=0;
			int num=0;
			while(1){
				s=getchar();
				if(s=='\n'){
					add(cnt,num);
					num=0;
					break;
				}
				if(s>='0'&&s<='9') num*=10,num+=s-'0',flag=1;
				else if(flag){
					add(cnt,num);
					num=0;
				}
			}
		}
		int l=1,r=n+1,mid;
		while(l<r){
			mid=(l+r)>>1;
			if(pd(mid)) r=mid;
			else l=mid+1;
		}
		cout<<l<<endl;
	}
	return 0;
} 

Optimal Milking

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof ar)
#define me1(ar) memset(ar,-1,sizeof ar)
const int N=235,INF=0x3f3f3f3f;
struct dot{
	int v,w;
}b[N][35];
int a[N][N],lin[35][N];
int k,c,m,ans=0;
bool vis[N];
bool cmp(dot x,dot y){
	return x.w<y.w;
}
bool dfs(int x,int d){
	rep(i,1,k){
		int v=b[x][i].v,w=b[x][i].w;
		if(w>d) return 0;
		if(vis[v]) continue;
		vis[v]=1;
		if(lin[v][0]<m){
			lin[v][++lin[v][0]]=x;
			return 1;
		}
		else rep(j,1,lin[v][0])
			if(dfs(lin[v][j],d)){
				lin[v][j]=x;
				return 1;
			}
	} 
	return 0;
}
bool lt(int d){
	me0(lin);
	rep(i,1,c){
		me0(vis);
		if(!dfs(i,d)) return 0;
	}
	return 1;
}
int main(){
	cin>>k>>c>>m;
	int kc=k+c,qm=0;
	rep(i,1,kc)
		rep(j,1,kc){
			cin>>a[i][j];
			if(i!=j&&!a[i][j]) a[i][j]=INF;
		}
	rep(p,1,kc)
		rep(i,1,kc)
			rep(j,1,kc)
				if(a[i][p]+a[p][j]<a[i][j]) a[i][j]=a[i][p]+a[p][j];
	rep(i,1,c){
		rep(j,1,k){
			b[i][j].v=j,b[i][j].w=a[k+i][j];
			if(a[k+i][j]!=INF) qm=max(qm,a[k+i][j]);
		}
		sort(b[i]+1,b[i]+k+1,cmp);
	}
	int l=1,r=qm+1;
	while(l<r){
		int mid=(l+r)>>1;
		if(lt(mid)) r=mid;
		else l=mid+1;
	}
	cout<<l;
	return 0;
} 

Steady Cow Assignment

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof ar)
#define me1(ar) memser(ar,-1,sizeof ar)
const int N=1e3+5;
int n,b;
int c[N],g[N][N],lin[N][N];
bool vis[N];
bool dfs(int p,int x,int y){
	rep(i,x,y){
		int v=g[p][i];
		if(vis[v]) continue;
		vis[v]=1;
		if(lin[v][0]<c[v]){
			lin[v][++lin[v][0]]=p;
			return 1;
		}
		rep(j,1,lin[v][0])
			if(dfs(lin[v][j],x,y)){
				lin[v][j]=p;
				return 1;
			}
	}
	return 0;
}
bool pd(int x,int y){
	me0(lin);
	rep(i,1,n){
		me0(vis);
		if(!dfs(i,x,y)) return 0;
	}
	return 1;
}
bool op(int d){
	rep(i,1,b-d)
		if(pd(i,i+d)) return 1;
	return 0;
}
int main(){
	while(cin>>n>>b){
		me0(g);
		me0(c);
		rep(i,1,n)
			rep(j,1,b) cin>>g[i][j];
		rep(i,1,b) cin>>c[i];
		int l=0,r=b,ans;
		while(l<r){
			int m=(l+r)>>1;
			if(op(m)) r=m;
			else l=m+1;
		}
		cout<<l+1<<endl;
	}
	return 0;
}

奔小康赚大钱

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm> 
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof ar)
#define me1(ar) memset(ar,-1,sizeof ar)
const int N=305,INF=0x3f3f3f3f;
int g[N][N],gap[N],exl[N],exr[N],lin[N],n;
bool visl[N],visr[N];
bool dfs(int x){
	visl[x]=1;
	rep(i,1,n){
		if(visr[i]) continue;
		int d=exl[x]+exr[i]-g[x][i];
		if(!d){
			visr[i]=1;
			if(!lin[i]||dfs(lin[i])){
				lin[i]=x;
				return 1;
			}
		}
		else if(gap[i]>d) gap[i]=d;
	}
	return 0;
} 
int main(){
	while(cin>>n){
		me0(lin);
		rep(i,1,n)
			rep(j,1,n){
				scanf("%d",&g[i][j]);
				exl[i]=max(exl[i],g[i][j]);
		}
		rep(i,1,n){
			rep(j,1,n) gap[j]=INF;
			while(1){
				me0(visl),me0(visr);
				if(dfs(i)) break;
				int d=INF;
				rep(j,1,n)
					if(!visr[j]) d=min(d,gap[j]);
				rep(j,1,n){
					if(visl[j]) exl[j]-=d;
					if(visr[j]) exr[j]+=d;
					else gap[j]-=d;
				}
			}
		}
		int ans=0;
		rep(i,1,n) ans+=g[lin[i]][i];
		cout<<ans<<endl;
	}
	return 0;
} 

Tour

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm> 
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof ar)
#define me1(ar) memset(ar,-1,sizeof ar)
const int N=405,M=6e4+5,INF=0x3f3f3f3f;
int n,m,cnt,l=INF;
int lin[N],exl[N],exr[N],g[N][N];
bool visl[N],visr[N];
bool dfs(int x){
	visl[x]=1;
	rep(v,1,n){
		if(visr[v]) continue;
		int gap=exl[x]+exr[v]-g[x][v];
		if(!gap){
			visr[v]=1;
			if(!lin[v]||dfs(lin[v])){
				lin[v]=x;
				return 1;
			}
		}
		else l=min(l,gap);
	}
	return 0;
}
int main(){
	int t;
	cnt=0;
	cin>>t;
	while(t--){
		cin>>n>>m;
		int u,v,w,ans=0,tmp=0;
		cnt=0;
		me0(lin),me0(exr);
		fill(exl+1,exl+n+1,-INF);
		rep(i,1,n)
			rep(j,1,n)
				g[i][j]=-INF;
		rep(i,1,m){
			cin>>u>>v>>w;
			g[u][v]=max(g[u][v],-w);
			exl[u]=max(g[u][v],exl[u]);
		}
		rep(i,1,n){
			while(1){
				me0(visl),me0(visr);
				if(dfs(i)) break;
				rep(j,1,n){
					if(visl[j]) exl[j]-=l;
					if(visr[j]) exr[j]+=l;
				}
			}
		}
		rep(i,1,n)
			ans+=g[lin[i]][i];
		cout<<-ans<<endl;
	}
	return 0;
}

Work Scheduling

#include<iostream>
#include<cstring>
#include<queue>
#define mem(a,b) memset(a,b,sizeof a)
const int maxn=230;
int par[maxn],pre[maxn],link[maxn],n,ans;
std::deque<int> q;
std::vector<int> g[maxn]={};
char ty[maxn];
int findp(int x){return x==par[x]?x:par[x]=findp(par[x]);}
int Ti=0,times[maxn]={};
int lca(int x,int y){
    for(Ti++;times[x]!=Ti;x^=y^=x^=y) 
        if(x) times[x]=Ti,x=findp(pre[link[x]]);
    return x;
}
void blossom(int x,int y,int p){
    while(findp(x)!=p){
        pre[x]=y;
        y=link[x];
        par[x]=par[y]=p;
        if(ty[y]==1) ty[y]=2,q.push_back(y);
        x=pre[y];
    }
}
bool Match(int x){
    for(int i=0;i<=n;i++) ty[i]=0,par[i]=i;
    q.clear();
    ty[x]=2,q.push_back(x);
    while(q.size()){
        x=q.front(),q.pop_front();
        for(int u:g[x])
            if(ty[u]==0){
                ty[u]=1;
                pre[u]=x;
                if(link[u]) q.push_back(link[u]),ty[link[u]]=2;
                else {
                    for(;x;u=x){
                        x=link[pre[u]];
                        link[u]=pre[u];
                        link[link[u]]=u;
                    }
                    return 1;
                }
            }
            else if(ty[u]==2&&findp(u)!=findp(x)){
                int p=lca(x,u);
                blossom(x,u,p),blossom(u,x,p);
            }
    }
    return 0;
}
int main(){
    mem(link,0);mem(pre,0);
    ans=0;
    scanf("%d",&n);
    for(int f,t;~scanf("%d%d",&f,&t);){
        g[f].push_back(t);
        g[t].push_back(f);
    }
    for(int i=1;i<=n;i++) 
        if(!link[i]&&Match(i)) ans++;
    printf("%d\n",ans*2);
    for(int i=1;i<=n;i++) if(i<link[i]) 
        printf("%d %d\n",i,link[i]);
}

Boke and Tsukkomi

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <cstdlib>
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
#define ll long long
using namespace std;
 
const int MAXN=50;
deque<int> Q;
bool g[MAXN][MAXN],inque[MAXN],inblossom[MAXN],vis[150];
int match[MAXN],pre[MAXN],base[MAXN];
int n,m,mmg;
vector<int>res;
struct node
{
    int u,v;
}com[150];
int findancestor(int u,int v){
    bool inpath[MAXN]={false};
    while(1){
        u=base[u];
        inpath[u]=true;
        if(match[u]==-1)break;
        u=pre[match[u]];
    }
    while(1){
        v=base[v];
        if(inpath[v])return v;
        v=pre[match[v]];
    }
}
void reset(int u,int anc){
    while(u!=anc){
        int v=match[u];
        inblossom[base[u]]=1;
        inblossom[base[v]]=1;
        v=pre[v];
        if(base[v]!=anc)pre[v]=match[u];
        u=v;
    }
}
 
void contract(int u,int v,int n){
    int anc=findancestor(u,v);
    memset(inblossom,0,sizeof(inblossom));
    reset(u,anc);reset(v,anc);
    if(base[u]!=anc)pre[u]=v;
    if(base[v]!=anc)pre[v]=u;
    for(int i=1;i<=n;i++)
        if(inblossom[base[i]]){
            base[i]=anc;
            if(!inque[i]){
                Q.push_back(i);
                inque[i]=1;
            }
        }
}
 
bool dfs(int S,int n){
    for(int i=0;i<=n;i++)pre[i]=-1,inque[i]=0,base[i]=i;
    Q.clear();Q.push_back(S);inque[S]=1;
    while(!Q.empty()){
        int u=Q.front();Q.pop_front();
        for(int v=1;v<=n;v++){
            if(g[u][v]&&base[v]!=base[u]&&match[u]!=v){
                if(v==S||(match[v]!=-1&&pre[match[v]]!=-1))contract(u,v,n);
                else if(pre[v]==-1){
                    pre[v]=u;
                    if(match[v]!=-1)Q.push_back(match[v]),inque[match[v]]=1;
                    else{
                        u=v;
                        while(u!=-1){
                            v=pre[u];
                            int w=match[v];
                            match[u]=v;
                            match[v]=u;
                            u=w;
                        }
                        return true;
                    }
                }
            }
        }
    }
    return false;
}
int MMG()
{
    int ans=0;
    memset(match,-1,sizeof(match));
    for(int i=1;i<=n;i++)
        if(match[i]==-1&&dfs(i,n)) ans++;
    return ans;
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&n,&m))
    {
        memset(g,false,sizeof(g));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            g[a][b]=g[b][a]=true;
            com[i].u=a;
            com[i].v=b;
        }
        mmg=MMG();
        res.clear();
        for(int i=1;i<=m;i++)
        {
            a=com[i].u;
            b=com[i].v;
            memset(g,false,sizeof(g));
            for(int j=1;j<=m;j++)
            if(j!=i)
            {
                int x=com[j].u,y=com[j].v;
                if(x==a||x==b||y==a||y==b) continue;
                g[x][y]=g[y][x]=true;
            }
            int t=MMG();
            if(t!=mmg-1) res.push_back(i);
        }
        printf("%d\n",res.size());
        if(res.size())
        printf("%d",res[0]);
        for(int i=1;i<res.size();i++)
        printf(" %d",res[i]);
        printf("\n");
    }
    return 0;
}

标签:11,专题,int,rep,memset,vis,2020,sizeof,lin
来源: https://blog.csdn.net/u013455437/article/details/111773728

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有