码迷,mamicode.com
首页 > 其他好文 > 详细

最大流

时间:2017-05-17 23:38:59      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:查询   准备   代码量   没有   ash   swap   turn   代码   裸题   

我之前并没有听说过树上差分这么高级的东东,于是为了练手速花了40min敲了一个树剖套线段树,写好了线段树的一堆函数定义(maketree() pushdown() query() update()),剩着函数内部等待填充,感觉到一种绝望:还有那么多,要敲到啥时候啊。。。正在调整心态准备敲线段树时,突然想到,这题好像只是区间修改、单点查询?!哇,得救啦![传送门](https://www.luogu.org/problem/show?pid=3368)
于是内心一片愉悦啊,愉快地敲完短得多的树状数组,顺利1A!
正经的题解:
增加一条x到y的路径,就是把x到y的所有点的点权加1,很容易想到这是树剖裸题的第一个操作([传送门](https://www.luogu.org/problem/show?pid=3384)),于是我很天真地套上了模板——树链剖分套线段树,但代码量对我这种手速不够的蒟蒻来说好长!于是急中生智换成了树状数组,代码少了整整90行(树剖裸题我的空行太多……)。上代码

  1 #include<bits/stdc++.h>
  2 #define lson(x) ((x)<<1)
  3 #define rson(x) (((x)<<1)|1)
  4 #define lowbit(x) (x)&(-(x))
  5 using namespace std;
  6 
  7 int n,k;
  8 
  9 struct Edge{
 10     int next,to;
 11 }e[100010];
 12 int cnt=1,head[50010];
 13 void add_e(int u,int v)
 14 {
 15     e[cnt].to=v;
 16     e[cnt].next=head[u];
 17     head[u]=cnt++;
 18 }
 19 
 20 struct tree{
 21     int fa;
 22     vector<int> son;
 23     int dep;
 24     int num_to;
 25     int wson;
 26     int top;
 27     int new_id;
 28 }t[50010];
 29 bool vis[50010];
 30 int dfs1(int u,int fa,int depth)
 31 {
 32     vis[u]=1;
 33     t[u].fa=fa;
 34     t[u].dep=depth;
 35     t[u].num_to=1;
 36     for(int i=head[u],weightest=-1,w;i;i=e[i].next)
 37     {
 38         int v=e[i].to;
 39         if(vis[v]) continue;
 40         t[u].son.push_back(v);
 41         w=dfs1(v,u,depth+1);
 42         if(w>weightest)
 43         {
 44             t[u].wson=v;
 45             weightest=w;
 46         }
 47         t[u].num_to+=w;
 48     }
 49     return t[u].num_to;
 50 }
 51 int num_id=1;
 52 void dfs2(int u,int top)
 53 {
 54     t[u].top=top;
 55     t[u].new_id=num_id++;
 56     int sz=t[u].son.size();
 57     if(sz==0)
 58         return;
 59     dfs2(t[u].wson,top);
 60     for(int i=0;i<sz;i++)
 61     {
 62         int v=t[u].son[i];
 63         if(v==t[u].wson) continue;
 64         dfs2(v,v);
 65     }
 66 }
 67 
 68 int s[50010]={0};
 69 void add(int node,int w)
 70 {
 71     while(node<n)
 72     {
 73         s[node]+=w;
 74         node+=lowbit(node);
 75     }
 76 }
 77 int ask(int node)
 78 {
 79     int ans=0;
 80     while(node)
 81     {
 82         ans+=s[node];
 83         node-=lowbit(node);
 84     }
 85     return ans;
 86 }
 87 
 88 void up(int x,int y)//////////////////////////////////////
 89 {
 90     while(t[x].top!=t[y].top)//x向y上靠 即y.top 更高 
 91     {
 92         if(t[t[x].top].dep<t[t[y].top].dep) swap(x,y);
 93         add(t[x].new_id-1,-1);
 94         add(t[t[x].top].new_id,1);
 95         x=t[t[x].top].fa;
 96     }
 97     if(t[x].new_id>t[y].new_id) swap(x,y);
 98     add(t[x].new_id,1);
 99     add(t[y].new_id+1,-1);
100 }
101 int main()
102 {
103     scanf("%d%d",&n,&k);
104     for(int i=1,x,y;i<n;i++)
105     {
106         scanf("%d%d",&x,&y);
107         add_e(x,y);
108         add_e(y,x);
109     }
110     dfs1(1,1,1);
111     dfs2(1,1);
112     
113     for(int i=0,x,y;i<k;i++)
114     {
115         scanf("%d%d",&x,&y);
116         up(x,y);
117     }
118     int maxn=s[1];
119     for(int i=2;i<=50001;i++)
120     {
121         maxn=max(maxn,ask(i));
122     }
123     printf("%d",maxn);
124     return 0;
125 }

 

最大流

标签:查询   准备   代码量   没有   ash   swap   turn   代码   裸题   

原文地址:http://www.cnblogs.com/wawcac-blog/p/6869850.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!