题目:
解题思路:
和主席树没有任何卵关系
还有这居然是一道黑题!!
我们把每个byx的人和S连边,流量为寿命
把每个手气君的人和T连边,流量为寿命
对于每个J,寿命加上本方膜法师的数量
然后跑一边模板Dinic
Accepted code:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define inf 1e9
using namespace std;
queue<int> q;
int n,m,s,t,cnt,x,y,w,byx,sqj;
int dis[10005],last[200005];
struct node{
int to,c,next;
}e[200005];
char b[105][5], a[105][5];
void add(int x,int y,int w)
{
e[++cnt].to=y;e[cnt].c=w;e[cnt].next=last[x];last[x]=cnt;
e[++cnt].to=x;e[cnt].c=0;e[cnt].next=last[y];last[y]=cnt;
}
bool bfs()
{
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
queue<int> q;
q.push(s);
while (q.size())
{
int u=q.front();
q.pop();
for (int i=last[u];i;i=e[i].next)
{
int v=e[i].to;
if (dis[v]>dis[u]+1&&e[i].c)
{
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return (dis[t]<0x3f3f3f3f);
}
int dfs(int u,int low)
{
int lows=0;
if (u==t) return low;
for (int i=last[u];i;i=e[i].next)
{
int v=e[i].to;
if (dis[v]==dis[u]+1&&e[i].c)
{
lows=dfs(v,min(low,e[i].c));
if (!lows) continue;
e[i].c-=lows;
e[i^1].c+=lows;
return lows;
}
}
return 0;
}
int dinic()
{
int ans=0;
while (bfs()&&ans<=m)
ans+=dfs(s,inf);
return min(ans,m);
}
int main()
{
memset(last,-1,sizeof(last));
scanf("%d%d",&n,&m);
cnt=1; s=0; t=2*n+1;
for (int i=1;i<=n;i++)
{
cin>>a[i];
if (a[i][0]=='Y') ++byx;
}
for (int i=1;i<=n;i++)
{
cin>>b[i];
if (b[i][0]=='Y') ++sqj;
}
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
add(s,i,x+((a[i][0]=='J')?byx:0));
}
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
add(i+n,t,x+((b[i][0]=='J')?sqj:0));
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) {
if (a[i][0]=='H')
if (b[j][0]=='E'||b[j][0]=='W')
add(i,j+n,1);
if (a[i][0]=='W')
if (b[j][0]=='Y'||b[j][0]=='E')
add(i,j+n,1);
if (a[i][0]=='J')
if (b[j][0]=='H'||b[j][0]=='W')
add(i,j+n,1);
if (a[i][0]=='E')
if (b[j][0]=='Y'||b[j][0]=='J')
add(i,j+n,1);
if (a[i][0]=='Y')
if (b[j][0]=='J'||b[j][0]=='H')
add(i,j+n,1);
}
return printf("%d",dinic())&0;
}