hdu5452 Minimum Cut 树链剖分 + 标记贡献

来源:互联网 发布:windows hadoop2 安装 编辑:程序博客网 时间:2024/05/17 02:42
//hdu5452 Minimum Cut 树链剖分 + 标记贡献////解题思路:////比赛的时候,大神给出了思路.对于给定的一条边u,v//一定会在树上与LCA(u,v)形成一个环.这条边所作出的贡献//就是u-v路径上所有的边都加一.最后求出边的最小的权值//然后加1.开始用了一个线段树维护.然后果断TLE了.在我//绝望的时候,发现了一篇大神直接模拟的过法.对于一个区间//[L,R]同时+x,等价于同时对[L,N]+x,[R+1,N]-x进行这两个//操作.用一个一维数组对于区间端点进行标记.表示的是//c[i]对于[i,N]的贡献,累加即可~~~~学到啦~~在此谢谢所以//的大神,小子会继续努力!#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define cls(x,a) memset(x,a,sizeof(x))using namespace std;const int MAX_M = 200088;const int MAX_N = 20008;const int INF = 0x7fffffff;int N,M;int num;int id;int idx[MAX_N];int father[MAX_N];int top[MAX_N];int dep[MAX_N];int siz[MAX_N];int son[MAX_N];int rk[MAX_N];int head[MAX_N];struct adj{int to;int next;adj(){}adj(int a,int b):to(a),next(b){}}edges[MAX_M<<1];struct node{int u;int v;node(){}node(int u,int v):u(u),v(v){}}e[MAX_M];void add_edges(int u,int v){edges[num] = adj(v,head[u]);head[u] = num++;}void input(){scanf("%d%d",&N,&M);num = 0;id = 1;for (int i = 1;i <= M;i ++ ){int u,v;scanf("%d%d",&u,&v);e[i] = node(u,v);}cls(head,-1);cls(siz,0);for (int i = 1;i < N;i ++){add_edges(e[i].u,e[i].v);add_edges(e[i].v,e[i].u);}}void dfs(int u,int fa,int d){father[u] = fa;dep[u] = d;siz[u] = 1;son[u] = 0;for (int i = head[u];i + 1; i = edges[i].next){int v = edges[i].to;if (v == fa)continue;dfs(v,u,d+1);siz[u] += siz[v];if (siz[son[u]] < siz[v])son[u] = v;}}void dfs(int u,int tp){top[u] = tp;idx[u] = id++;rk[idx[u]] = u;if (son[u])dfs(son[u],tp);for (int i = head[u];i + 1 ;i = edges[i].next){int v = edges[i].to;if (v == father[u] || v == son[u])continue;dfs(v,v);}}void p(){for (int i = 1;i <= N;i ++)printf("idx %d =  %d\n",i,idx[i]);}void split(){dfs(1,0,0);dfs(1,1);//p();}//int vmin[MAX_N<<2];//int laz[MAX_N<<2];//int ql,qr;//#define lson(x)(x<<1)//#define rson(x)(x<<1|1)////void push_up(int ro){//vmin[ro] = min(vmin[lson(ro)],vmin[rson(ro)]);////}////void push_down(int ro,int L,int R){//if (L == R)return ;//if (laz[ro]){//laz[lson(ro)] += laz[ro];//laz[rson(ro)] += laz[ro];//vmin[lson(ro)] += laz[lson(ro)];//vmin[rson(ro)] += laz[rson(ro)];//laz[ro] = 0;//}//}////void build(int ro,int L,int R){//laz[ro] = 0;//if (L == R){//if (L!=1)//vmin[ro] = 1;//return ;//}//int M = (L + R) >> 1;//build(lson(ro),L,M);//build(rson(ro),M+1,R);//push_up(ro);//}////void update(int ro,int L,int R){////////printf("ro = %d minv[ro] = %d laz[ro] = %d L = %d R = %d\n",ro,vmin[ro],laz[ro],L,R);////if (ql <= L && R <= qr){////laz[ro]++;//vmin[ro] += laz[ro];//////printf("--------ro = %d minv[ro] = %d laz[ro] = %d l = %d r = %d\n",ro,vmin[ro],laz[ro],L,R);//return ;//}//int M = (L + R) >> 1;//push_down(ro,L,R);//if (ql <= M)update(lson(ro),L,M);////if (M < qr)update(rson(ro),M+1,R);////push_up(ro);//}//////int query(int ro,int L,int R){//if (ql <= L && R <= qr){//return vmin[ro];//}////int M = (L + R) >> 1;//int ans = INF;//push_down(ro,L,R);////if (ql <= M)ans = min(ans,query(lson(ro),L,M));//if (M < qr)ans = min(ans,query(rson(ro),M+1,R));////return ans;//}//////void print(int ro,int L,int R){//////printf("ro = %d minv[ro] = %d laz[ro] = %d L = %d R = %d\n",ro,vmin[ro],laz[ro],L,R);//if (L==R){//return;//}//int M = (L + R) >> 1;////print(lson(ro),L,M);//print(rson(ro),M+1,R);//}//void change(int u,int v){//int p = top[u],q = top[v];////puts("change :");//while(p != q){//if (dep[p] < dep[q]){//swap(p,q);//swap(u,v);//}//ql = idx[p];//qr = idx[u];//////printf("ql = %d qr = %d\n",ql,qr);////update(1,1,N);////cout << endl;////print(1,1,N);////cout << endl;////u = father[p];//p = top[u];//}////if (u == v)//return ;////if (dep[u] > dep[v])//swap(u,v);//ql = idx[son[u]];//qr = idx[v];////////printf("ql = %d qr = %d\n",ql,qr);////update(1,1,N);////cout << endl;////print(1,1,N);////cout << endl;//}int sum[MAX_N];void get(int u,int v){int p = top[u],q = top[v];while(p != q){if (dep[p] < dep[q]){swap(p,q);swap(u,v);}sum[idx[p]]++;sum[idx[u]+1]--;u = father[p];p = top[u];}if (u == v)return ;if(dep[u] > dep[v])swap(u,v);sum[idx[son[u]]]++;sum[idx[v]+1]--;}void solve(){//build(1,1,N);cls(sum,0);for (int i = 1;i < N ;i ++){if (dep[e[i].u] < dep[e[i].v])swap(e[i].u,e[i].v);//ql = idx[e[i].u];//qr = idx[e[i].u];//update(1,1,N);}//print(1,1,N);//cout << endl;for (int i = N;i <= M ;i ++){get(e[i].u,e[i].v);//print(1,1,N);//cout << endl;}//ql = 2, qr = N;//print(1,1,N);int ans = INF;for (int i = 2;i <= N;i ++){sum[i] +=sum[i-1];ans = min(ans,sum[i]);}//ans = min(ans,query(1,1,N));//for (int i = 1 ;i< N;i ++){//ql = qr = idx[e[i].u];//////printf("ql = %d qr = %d\n",ql,qr);////ans = min(ans,query(1,1,N));////cout << ans << endl;//}printf("%d\n",ans+1);}int main(){int t;//freopen("1.txt","r",stdin);scanf("%d",&t);int kase = 1;while(t--){printf("Case #%d: ",kase++);input();split();solve();}}

0 0
原创粉丝点击