第一道题是最大费用最大流
第二道题是找最短路再找最大流
第三道题在图上有三种方块,未知 , 陆地,和海洋 现在找有多少个岛
先在陆地旁去掉所有未知改为海洋
然后奇数偶数建边找最大点独立集
用原来陆地数量加上最大点独立集就是答案了
明天来继续做第二题
#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
*/