Always Online hdu 6350

news/2024/11/7 23:55:27/

ps:今天真是石乐志,改了一下午bug,结果是忘了排序。。。。。。。。。。这题姿势较多,坑点就一个。

题解:有个结论,任意两点之间如果至多存在两条不相交路径,那么每一条边至多出现在一个环中(very important !)。如果一个s - t割要割掉某个环中的边,那么割掉的边顶多只能是两条,且这个环中最小容量的边一定会被割掉。所以我们可以割掉每个环中的最小容量边,并把其容量加到这个环中的其它边上。这样并不会影响任意两点间的最大流,且把图降为一棵树,而最大流也简化成了两点之间路径上的容量最小的。考虑将容量按降序插入空树中,那么当前要加的边必然是两个联通块A,B的最小割,话句话说,割掉这条边,A,B集合中的点一定不联通,所以这条边的容量就是 u - v 的最大流(u ∈ A, v∈B)。位运算一般都要考虑二进制,算每一位的贡献,所以枚举权重就好了。注意爆long long

#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define P pair<int, int>
#define pb push_back
#define mp make_pair
#define pp pop_back
#define lson root << 1
#define INF (int)2e9 + 7
#define rson root << 1 | 1
#define LINF (unsigned long long int)1e18
#define sc(x) scanf("%d", &x)
#define pr(x) printf("%d\n", x)
#define mem(arry, in) memset(arry, in, sizeof(arry))
using namespace std;inline void upd(int &x, int y) {x < y && (x = y);
}const int N = 300005;ull ans, cnt[N][32][2];
int T, n, m, dep[N], pa[N], fa[N], id[N];
bool use[N];struct mode { int u, v, w; } eg[N], sg[N];inline bool cmp(mode& a, mode& b) {return a.w > b.w;
}int getFa(int a) {return (a == fa[a] ? a : fa[a] = getFa(fa[a]));
}bool Union(int a, int b) {int x = getFa(a);int y = getFa(b);if (x != y) {fa[x] = y;return true;}return false;
}vector<P> g[N];void Inite() {for (int i = 1; i <= n; ++i) {g[i].clear();for (int j = 0; j < 32; ++j) {cnt[i][j][0] = ((i >> j) & 1) ^ 1;cnt[i][j][1] = ((i >> j) & 1);}}
}void DFS(int u, int p) {pa[u] = p;for (auto v : g[u]) if (p != v.first) {id[v.first] = v.second;dep[v.first] = dep[u] + 1;DFS(v.first, u);}
}void change(int u, int v, int w) {if (u == v) return;if (dep[u] < dep[v]) swap(u, v);while (dep[u] != dep[v]) {eg[id[u]].w += w;u = pa[u];}while (u != v) {eg[id[u]].w += w, eg[id[v]].w += w;u = pa[u], v = pa[v];}
}void compute(int u, int v, int w) {u = getFa(u);v = getFa(v);for (ull i = 0; i < 31; ++i) {if (w & (1ull << i)) {ans += cnt[u][i][0] * cnt[v][i][0] * (1ull << i);ans += cnt[u][i][1] * cnt[v][i][1] * (1ull << i);}else {ans += cnt[u][i][0] * cnt[v][i][1] * (1ull << i);ans += cnt[u][i][1] * cnt[v][i][0] * (1ull << i);}}fa[u] = v;for (int i = 0; i < 31; ++i) {cnt[v][i][0] += cnt[u][i][0];cnt[v][i][1] += cnt[u][i][1];}
}int main()
{//freopen("D:\\1001.in","r",stdin);//freopen("D:\\1.txt","w",stdout);
sc(T);while (T--) {sc(n), sc(m);Inite();for (int i = 1; i <= m; ++i) {use[i] = 0;scanf("%d %d %d", &eg[i].u, &eg[i].v, &eg[i].w);}sort(eg + 1, eg + m + 1, cmp);for (int i = 1; i <= n; ++i) fa[i] = i;for (int i = 1; i <= m; ++i) if (Union(eg[i].u, eg[i].v)) {use[i] = 1;g[eg[i].u].pb(P(eg[i].v, i));g[eg[i].v].pb(P(eg[i].u, i));}dep[1] = 0;DFS(1, -1);for (int i = 1; i <= m; ++i) if (!use[i]) change(eg[i].u, eg[i].v, eg[i].w);int tot = 0;for (int i = 1; i <= m; ++i) if (use[i]) sg[++tot] = eg[i];sort(sg + 1, sg + tot + 1, cmp);  // 一定要重排一道,因为边的权重发生了变化,WA了一下午
ans = 0;for (int i = 1; i <= n; ++i) fa[i] = i;for (int i = 1; i <= tot; ++i) compute(sg[i].u, sg[i].v, sg[i].w);printf("%llu\n", ans);}return 0;
}

 

转载于:https://www.cnblogs.com/zgglj-com/p/9458019.html


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

相关文章

快狗打车开启招股:奇瑞、广发为基石,二者合计认购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…

hdu - 6350

Topic 题目链接 Always Online Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 208 Accepted Submission(s): 66 Problem Description Wayne is an administrator of some metropolitan area network. The n…

HDU 6350 Always Online——仙人掌图

思路&#xff1a;把每个环的最小边去掉&#xff0c;加在环的其他边上&#xff0c;然后并查集跑一下就可以&#xff0c;跑的时候维护一下某位为1的点有多少个 #include <cstdio> #include <vector> #include <iostream> #include <algorithm> u…

HDU 6350 Always Online (仙人掌图,最大流)

传送门 这道题真的是坑&#xff0c;竟然用ull&#xff0c;ll都会爆。 首先这是一个仙人掌图。题意让求任意两点最大流&#xff0c;再进行异或。先说最大流&#xff0c;对于环上任意两点最大流&#xff0c;就是两条路径最小的边和&#xff0c;这就等效于求出环中最小的边&…

MTK Android5.1 单独调整主副麦的模拟增益PGA(MT6350_PMIC)

MTK Android5.1 单独调整主副麦的模拟增益PGA&#xff08;MT6350_PMIC&#xff09; 项目使用副麦消噪&#xff0c;但是副麦增益太小&#xff0c;需要单独修改副麦增益&#xff0c;使用工程模式APP和Audio Tuning Tool调整的MIC的Level4的值&#xff0c;都会同时调整主麦和副麦…

HDU 6350 Always Online(最大流+并查集)

Description 给出一个 n n 个点m" role="presentation" style="position: relative;">mm条边的无向图&#xff0c;任意两点之间至多两条路径&#xff0c;以 flow(s,t) f l o w ( s , t ) 表示 s,t s , t 两点之间的最大流&#xff0c;求 ∑1≤s&l…

zabbix通过SNMP V3监控华为防火墙USG6350

1.华为防火墙开启snmp V3(图形界面配置) 防火墙接口开启SNMP服务&#xff08;找到通往zabbix服务器的那个网络接口或VLAN&#xff0c;这步很重要&#xff01;&#xff09; 找到通往zabbix服务器的那个网络接口或VLAN 防火墙配置完成&#xff01; 2.配置zabbix服务器端 yum …