【仙人掌?】【并查集】HDU6350 Always Online

news/2024/12/21 22:27:30/

分析:

考场上看都没看的题。。。但实现起来居然异常简单(相对于隔壁D题动态点分治而言)。。。。

这题除了利用了仙人掌图的定义。。其它都和仙人掌没关系。。。

先考虑一个相对简单的问题:

如果给的是棵树,怎么求答案?

树的性质无非就是两点间路径唯一,也就是说,这里的“最大流”可以看作两点间路径上的边权最小值。

从大到小加入边。每次加入时,因为两端点所在的联通块中,这条边边权一定是最小的(比它边权小的边都还没加入)。那么这两个联通块之间的路径最小值一定可以在当前这条边上取到。所以就可以算出这条边对最终答案的贡献。

由于题目非常鬼畜地要异或点的编号,所以这里求贡献还是需要一点技巧:

用并查集维护每个点所在的联通块中,编号在二进制下第 k k 位为0、为1的点的数量,设为sumk0 sumk1 s u m k 1

我们可以按边权在二进制下的每一位,分别求贡献。

若边权二进制下第 i i 位为1,那么就要求两个点的编号在第i位的值必须相同(否则xor之后就是0了),
这部分的贡献就是 (sumi0(u)sumi0(v)+sumi1(u)sumi1(v))2i ( s u m i 0 ( u ) ∗ s u m i 0 ( v ) + s u m i 1 ( u ) ∗ s u m i 1 ( v ) ) ∗ 2 i

若边权二进制下第 i i 位为0,那么就要求两个点的编号在第i位的值必须不同

这部分的贡献就是 (sumi0(u)sumi1(v)+sumi1(u)sumi0(v))2i ( s u m i 0 ( u ) ∗ s u m i 1 ( v ) + s u m i 1 ( u ) ∗ s u m i 0 ( v ) ) ∗ 2 i

仙人掌图如何求答案?

这里又要利用最小割最大流定理了,找两个点之间的最大流,无非就是在这两个点之间找一条最小割。结合仙人掌图的定义:每条边最多出现在一个简单环中。那么最小割只有两种情况:删去某个环上的两条边、或删去一条树边(即不在简单环上的边)。
这里写图片描述

而且如果删去环上的边,必然会删去这个环上边权最小的一条

那么可以把每个环上边权最小的边删去,然后把其余的边全部加上这条边的权值即可。因为割去这个环上任意一条边,都会割去最小边,那么可以直接把最小边的代价加到其他边里面去,然后删去最小边。

由于每条边最多在一个简单环里,所以这里的加权操作可以直接暴力搞。

这个骚操作之后,这个图就变成一颗树了。。。。然后就可以按照上面的做法过掉了。。。

这题数据范围卡得很好啊。。unsigned long long 才能过。。。是不是考场上很多人被这个坑了所以过的人不多?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 300010
using namespace std;
typedef unsigned long long ull;
ull ans=0;
int cnt;
int fa[MAXN];
ull siz[MAXN][32][2];
struct node{int u,v;int val;node () {}node (int u1,int v1,int val1):u(u1),v(v1),val(val1) {}bool operator < (const node &a) const {return val>a.val;}
}l[MAXN];
int dep[MAXN],fai[MAXN],soi[MAXN];
vector<int> a[MAXN];
vector<ull> w[MAXN];
bool used[MAXN];
void dfs(int x,int f,int id){dep[x]=dep[f]+1;soi[x]=id;for(int i=0;i<a[x].size();i++){int u=a[x][i];if(u==f){fai[x]=i;continue;}dfs(u,x,i);}   
}
void add(int x,int y,int val){if(x==y)return ;if(dep[x]<dep[y])swap(x,y);while(dep[x]!=dep[y]){int f=a[x][fai[x]];w[x][fai[x]]+=val;w[f][soi[x]]+=val;x=f;}while(x!=y){int f=a[x][fai[x]];w[x][fai[x]]+=val;w[f][soi[x]]+=val;x=f;f=a[y][fai[y]];w[y][fai[y]]+=val;w[f][soi[y]]+=val;y=f;}
}
void dfs1(int x,int f){for(int i=0;i<a[x].size();i++){int u=a[x][i];if(u==f)continue;l[++cnt]=node(x,u,w[x][i]);dfs1(u,x);}
}
int get_fa(int x){if(fa[x]==0)return x;fa[x]=get_fa(fa[x]);return fa[x];   
}
void merge(int x,int y,int val){x=get_fa(x);y=get_fa(y);for(ull i=0;i<31;i++){if(val&(1ull<<i)){ans+=siz[x][i][0]*siz[y][i][0]*(1ull<<i);ans+=siz[x][i][1]*siz[y][i][1]*(1ull<<i);}else{ans+=siz[x][i][0]*siz[y][i][1]*(1ull<<i);ans+=siz[x][i][1]*siz[y][i][0]*(1ull<<i);}}fa[x]=y;for(int i=0;i<31;i++){siz[y][i][0]+=siz[x][i][0];siz[y][i][1]+=siz[x][i][1];}
}
int main(){//freopen("1001.in","r",stdin);//freopen("1.txt","w",stdout);int t;SF("%d",&t);while(t--){int n,m;SF("%d%d",&n,&m);for(int i=1;i<=n;i++){fa[i]=0;dep[i]=0;   for(int j=0;j<31;j++){siz[i][j][0]=((i>>j)&1)^1;siz[i][j][1]=((i>>j)&1);}a[i].clear();w[i].clear();}for(int i=1;i<=m;i++){SF("%d%d%d",&l[i].u,&l[i].v,&l[i].val);used[i]=0;}sort(l+1,l+1+m);for(int i=1;i<=m;i++){int fu=get_fa(l[i].u);int fv=get_fa(l[i].v);if(fu!=fv){used[i]=1;fa[fu]=fv;a[l[i].u].push_back(l[i].v);a[l[i].v].push_back(l[i].u);w[l[i].u].push_back(l[i].val);w[l[i].v].push_back(l[i].val);}}dfs(1,0,0);for(int i=1;i<=n;i++)fa[i]=0;for(int i=1;i<=m;i++)if(used[i]==0)add(l[i].u,l[i].v,l[i].val);cnt=0;dfs1(1,0);sort(l+1,l+n);ans=0;for(int i=1;i<n;i++)merge(l[i].u,l[i].v,l[i].val);PF("%llu\n",ans);}
}

http://www.ppmy.cn/news/172602.html

相关文章

CVE-2014-6350之CFreeMarshaler反序列化执行原理

原文:https://googleprojectzero.blogspot.kr/2014/12/, com组件在列集(Marshal)一个远程com对象时会QueryInterface它的IMarshal接口,只要在GetUnmarshalClass时返回CLSID_InProcFreeMarshaler就可以使用CFreeMarshaler来作为IMarshal接口Unmarshal,接下来就是反序列化执行的…

[HDU - 6350] Always Online

题目链接 https://vjudge.net/contest/252211#problem/A 题目大意 T组数据 (T≤100) ( T ≤ 100 ) , 给出一个n个点m条边的无向图 (1≤n≤105,n−1≤m≤32(n−1)) ( 1 ≤ n ≤ 10 5 , n − 1 ≤ m ≤ 3 2 ( n − 1 ) ) &#xff0c; 每条边有容量 wi(1≤wi≤109) w i ( 1 ≤…

Internet Explorer EPM沙盒跳出漏洞的分析(CVE-2014-6350)

blast 2014/12/04 9:42 0x00 前言 作者: James Forshaw 原文: 链接 这个月微软修复了3个不同的IE增强保护模式EPM的沙盒跳出漏洞&#xff0c;这些漏洞由我&#xff08;原作者&#xff0c;下同&#xff09;在8月披露。沙盒是Project Zero&#xff08;我也参加了&#xff09;中最…

pytest文档21-pytest-html报告优化(nodeid中文显示[\u6350\u52a9\u6211\u4eec]问题解决)

前言 pytest-html报告中当用到参数化时候&#xff0c;获取用例的nodeid里面有中文时候&#xff0c;会显示[\u6350\u52a9\u6211\u4eec]这种编码&#xff08;再次声明&#xff0c;这个不叫乱码&#xff0c;这是unicode编码&#xff09; 关于python2和python3里面Unicode编码转化…

【JZOJ6350】考试(test)

description analysis 对于\(n0\)的点&#xff0c;直接模拟就好了状压\(DP\)&#xff0c;设\(f[i][j][S]\)表示到第\(i\)题、连续\(GG\)了\(j\)题、喝的饮料集合为\(S\)的最大答案由于一题可以喝多瓶饮料所以转移需要枚举\(S\)的子集\(SS\)来转移然后转移比较显然但是细节恶心我…

Always Online hdu 6350

ps&#xff1a;今天真是石乐志&#xff0c;改了一下午bug&#xff0c;结果是忘了排序。。。。。。。。。。这题姿势较多&#xff0c;坑点就一个。 题解&#xff1a;有个结论&#xff0c;任意两点之间如果至多存在两条不相交路径&#xff0c;那么每一条边至多出现在一个环中&…

快狗打车开启招股:奇瑞、广发为基石,二者合计认购6350万美元

6月14日&#xff0c;快狗打车&#xff08;HK:02246&#xff09;在港交所发布公告&#xff0c;拟全球发售3120万股股份&#xff0c;其中香港发售股份312万股&#xff0c;国际发售股份2808万股&#xff0c;另有15%超额配股权。发售价将为每股发售股份21.5港元&#xff0c;预期股份…

hdu6350 /// tarjan+并查集+组合+最大流思想

题目大意&#xff1a; 给定n个点 m条边没有重边的仙人掌图&#xff08;没有一条边会同时存在与两个环 也就是环都是相互独立的&#xff09; 求任意两点间 i^j^maxflow(i,j)的总和 maxflow为两点间最大流 题解&#xff1a;https://blog.csdn.net/du_lun/article/details/8161062…