三道让我很难受的题

第一道题是最大费用最大流

第二道题是找最短路再找最大流

第三道题在图上有三种方块,未知 , 陆地,和海洋  现在找有多少个岛

先在陆地旁去掉所有未知改为海洋

然后奇数偶数建边找最大点独立集

用原来陆地数量加上最大点独立集就是答案了

明天来继续做第二题

#include<bits/stdc++.h>
using namespace std;
char earth[45][45];
bool pd[2500];
int n,m,link[2500],num[45][45],ans,shu;
int van,sum[45][45],tot,all,to[30005],head[30005],next[30005];
void add(int x,int y)
{
	to[++tot]=y;
	next[tot]=head[x];
	head[x]=tot;
}
bool find(int x)
{
	for(int i=head[x];i;i=next[i])
	{
		int y=to[i];
		if(!pd[y])
		{
			pd[y]=1;
			if(!link[y]||find(link[y]))
			{
				link[y]=x;
				return true;
			}
		}
	}
	return false;
}
void dfs(int x,int y)
{
	earth[x][y]='W';
	if(earth[x+1][y]=='L')
	{
		dfs(x+1,y);
	}
	if(earth[x-1][y]=='L')
	{
		dfs(x-1,y);
	}
	if(earth[x][y+1]=='L')
	{
		dfs(x,y+1);
	}
	if(earth[x][y-1]=='L')
	{
		dfs(x,y-1);
	}
}
int main()
{
	freopen("island.in","r",stdin);
	freopen("island.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("\n");
		for(int j=1;j<=m;j++)
		{
			scanf("%c",&earth[i][j]);
		}	
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if(i!=1)
			num[i][j]=num[i-1][j]+1;
		else 
			num[i][j]=num[i][j-1]+1;
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			sum[i][j]=++van;
for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if(earth[i][j]=='L')
		{
			if(earth[i+1][j]=='C')
			{
				earth[i+1][j]='W';
			}
			if(earth[i-1][j]=='C')
			{
				earth[i-1][j]='W';
			}
			if(earth[i][j+1]=='C')
			{
				earth[i][j+1]='W';
			}
			if(earth[i][j-1]=='C')
			{
				earth[i][j-1]='W';
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(earth[i][j]=='C') ans++;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			if(num[i][j]%2&&earth[i][j]=='C')
			{
				if(earth[i+1][j]=='C')
				{
					add(sum[i][j],sum[i+1][j]);
				}
				if(earth[i-1][j]=='C')
				{
					add(sum[i][j],sum[i-1][j]);
				}
				if(earth[i][j+1]=='C')
				{
					add(sum[i][j],sum[i][j+1]);
				}
				if(earth[i][j-1]=='C')
				{
					add(sum[i][j],sum[i][j-1]);
				}
			}
		}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		memset(pd,0,sizeof(pd));
		if(num[i][j]%2&&find(sum[i][j]))
		all++;
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		if(earth[i][j]=='L')
		{
			shu++;
			dfs(i,j);
		}
	ans=ans-all+shu;
	cout<<ans;
	return 0;
}
/*
14 6
WWWWWW
WLLWLW
WCCCCW
WCCCCW
WCCCCW
WLWLLW
WWWWWW
WWWWWW
WLLWLW
WCCCCW
WCCCCW
WCCCCW
WLWLLW
WWWWWW
*/

#include<bits/stdc++.h>
using namespace std;
int tot=1,head[30005],next[30005],remain[30005];
int dis[30005],n,p,q,a[3005],b[3005];
int to[30005],pree[3005],prev[3005],worth[30005];
bool pd[30005];
queue <int> que;
void add(int x,int y,int z,int g)
{
	to[++tot]=y;
	next[tot]=head[x];
	head[x]=tot;
	remain[tot]=g;
	worth[tot]=z;
	to[++tot]=x;
	next[tot]=head[y];
	head[y]=tot;
	remain[tot]=0;
	worth[tot]=-z;
}
bool spfa()
{
	memset(dis,128,4*(n+5));
	memset(pd,0,4*(n+5));
	que.push(1);
	pd[1]=1;
	dis[1]=0;
	while(!que.empty())
	{
		int x=que.front();
		que.pop();
		pd[x]=0;
		for(int i=head[x];i;i=next[i])
		{
			int y=to[i];
			if(remain[i]&&dis[y]<dis[x]+worth[i])
			{
				dis[y]=dis[x]+worth[i];
				pree[y]=x;
				prev[y]=i;
				if(!pd[y])
				{
					que.push(y);
					pd[y]=1;
				}
			}
		}
	}
	return dis[n+4]>dis[0];
}
int mountain()
{
	int x=n+4;
	int all=0;
	while(x!=1)
	{
		remain[prev[x]]-=1;
		remain[prev[x]^1]+=1;
		x=pree[x];
	}
	return dis[n+4];
}
int main()
{
	freopen("choice.in","r",stdin);
	freopen("choice.out","w",stdout);
	cin>>n>>p>>q;
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	scanf("%d",&b[i]);
	for(int i=2;i<=n+1;i++)
	add(1,i,0,1);
	for(int i=1;i<=n;i++)
	add(i+1,n+2,a[i],1);
	for(int i=1;i<=n;i++)
	add(i+1,n+3,b[i],1);
	add(n+2,n+4,0,p);
	add(n+3,n+4,0,q);
	int ans=0;
	while(spfa())
	{
		ans+=mountain();
	}
	cout<<ans;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
bool pd[10005],pd2[10005];
int tot=1,head[50005],next[50005],remain[50005],re[50005],w[50005];
int dis[50005],n,m,hh[50005],t,tot2=1,to2[50005],next2[50005],head2[50005];
int lu2[50005],to[50005],shu1,shu2,shu3,ans,lu1[50005];
queue <int> que;
void add(int x,int y,int z,int g)
{
	to[++tot]=y;
	next[tot]=head[x];
	head[x]=tot;
	re[tot]=z;
	w[tot]=g;
}
void add_edge(int x,int y,int z)
{
	to2[++tot2]=y;
	next2[tot2]=head2[x];
	head2[x]=tot2;
	remain[tot2]=z;
	to2[++tot2]=x;
	next2[tot2]=head2[y];
	head2[y]=tot2;
	remain[tot2]=0;
}
void spfa1()
{
	memset(lu1,127,4*(n+10));
	memset(pd,0,4*(n+10));
	que.push(1);
	pd[1]=1;
	lu1[1]=0;
	while(!que.empty())
	{
		int x=que.front();
		que.pop();
		pd[x]=0;
		for(int i=head[x];i;i=next[i])
		{
			int y=to[i];
			if(lu1[y]>lu1[x]+w[i])
			{
				lu1[y]=lu1[x]+w[i];
				if(!pd[y])
				{
					que.push(y);
					pd[y]=1;
				}
			}
		}
	}
}
void spfa2()
{
	memset(lu2,127,4*(n+10));
	memset(pd,0,4*(n+10));
	que.push(n);
	pd[n]=1;
	lu2[n]=0;
	while(!que.empty())
	{
		int x=que.front();
		que.pop();
		pd[x]=0;
		for(int i=head[x];i;i=next[i])
		{
			int y=to[i];
			if(lu2[y]>lu2[x]+w[i])
			{
				lu2[y]=lu2[x]+w[i];
				if(!pd[y])
				{
					que.push(y);
					pd[y]=1;
				}
			}
		}
	}
}
bool bfs()
{
	memset(dis,0,4*n+40);
	memset(pd2,0,4*n+40);
	que.push(1);
	pd2[1]=1;
	dis[1]=0;
	while(!que.empty())
	{
		int x=que.front();
		que.pop();
		for(int i=head2[x];i;i=next2[i])
		{
			int y=to2[i];
			if(!pd2[y]&&remain[i])
			{
				dis[y]=dis[x]+1;
				que.push(y);
				pd2[y]=1;
			}
		}
	}
	return pd2[n];
}
int dfs(int x,int delta)
{
	if(x==n)
	return delta;
	int all=0;
	for(int i=hh[x];i;i=next2[i])
	{
		int y=to2[i];
		if(dis[y]==dis[x]+1&&remain[i])
		{
			int shu=dfs(y,min(remain[i],delta));
			remain[i]-=shu;
			remain[i^1]+=shu;
			delta-=shu;
			all+=shu;
			hh[x]=next[i];
		}
	}
	return all;
}
int main()
{
	freopen("roadblock.in","r",stdin);
	freopen("roadblock.out","w",stdout);
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		ans=0;
		tot=1;
		tot2=1;
		memset(head2,0,4*n+40);
		memset(head,0,4*n+40);
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d%d",&shu1,&shu2,&shu3);
			add(shu1,shu2,shu3,1);
			add(shu2,shu1,shu3,1);
		}
		spfa1();
		spfa2();
		for(int i=1;i<=n;i++)
			for(int j=head[i];j;j=next[j])
			{
				int y=to[j];
				if(lu1[i]+lu2[y]+1==lu1[n])
					add_edge(i,y,re[j]);
			}
		while(bfs())
		{
			for(int i=1;i<=n;i++)
				hh[i]=head2[i];
			ans+=dfs(1,0x7fffffff);
		}
		printf("%d\n",ans);
	}
	
	return 0;
}
/*
3
4 4
1 2 1
2 4 2
3 1 3
4 3 4
4 4
1 2 1
2 4 2
3 1 3
4 3 4
4 4
1 2 1
2 4 2
3 1 3
4 3 4
*/

猜你喜欢

转载自blog.csdn.net/enesama/article/details/79357518