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
浙公网安备 33010602011771号