您的位置:首页 > 其它

[USACO15DEC]最大流Max Flow题解

2017-03-01 18:48 381 查看
题目:https://www.luogu.org/problem/show?pid=3128

题解

从一个点运输牛奶到另一个点,求最大压力的点是那个点?

很显然,运输牛奶是从一个点运输到这两个点的LCA之后再运到另一个点

最后是修改很显然一个点一个点去加一是TLE的所以,我们要用一个差分的思想:

用record[]数组,两个点各加一,LCA减一,LCA的父亲减一

最后用dfs搜索一遍就出答案了

代码

tarjan法求LCA,tmpfa存tarjan用的fa

fa只存这一点的上一级

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int n,q,ans;
int toq[600100],nxtq[600100],headq[300100],totq;
int top[600100],nxtp[600100],headp[300100],totp;
int tmpfa[300100],fa[300100],record[300100];
bool vis[300100];

void addq(int f,int t)
{
toq[++totq] = t;
nxtq[totq] = headq[f];
headq[f] = totq;
}

void addp(int f,int t)
{
top[++totp] = t;
nxtp[totp] = headp[f];
headp[f] = totp;
}

int find(int x){
if(tmpfa[x] == x)return x;
return tmpfa[x] = find(tmpfa[x]);
}

void tarjan(int pos,int pre)
{
tmpfa[pos] = pos;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
tarjan(top[i],pos);
tmpfa[top[i]] = pos;
}
vis[pos] = true;
for(int i = headq[pos];i;i = nxtq[i])
if(vis[toq[i]]){
int tmp_lca = find(toq[i]);
record[tmp_lca]--,record[fa[tmp_lca]]--,record[pos]++,record[toq[i]]++;
}
}

void dfs(int pos,int pre)
{
fa[pos] = pre;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre)
dfs(top[i],pos);
}

void dfsans(int pos,int pre)
{
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
dfsans(top[i],pos);
record[pos] += record[top[i]];
}
ans = max(record[pos],ans);
}

int main()
{
scanf("%d%d",&n,&q);
int f,t,ori;
for(int i = 1;i <  n;i++){
scanf("%d%d",&f,&t);
addp(f,t),addp(t,f);
}
for(int i = 1;i <= q;i++){
scanf("%d%d",&f,&t);
addq(f,t),addq(t,f);
}
dfs(1,0);
tarjan(1,0);
dfsans(1,0);
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCA USACO