【图论】hdu6073 Matching In Multiplication
来源:互联网 发布:西文文摘数据库 编辑:程序博客网 时间:2024/06/02 06:29
比赛的时候,一眼看到二分图,哇!掏出了dinic模板。之后发现,好像完全不是那么回事。隐隐约约有一点感觉,但就是没有清楚地理清思路。先找出一度节点就没有想到,非联通块更是不知道怎么处理。
本期官方题解说的特别清楚,强烈好评~~
先把一度节点挑出来,得到每个二分图都确定一样的边。
然后剩下一堆度数全部是二的联通快,每个联通快有两种匹配方式,间隔取边,分别得权值积num1,num2;
最后 ans = ans (num1+num2)(num1,num2)… …所有联通快的num1,num2;
有几个注意:
1. 去一度节点,可以不用拓扑那么高端(瑟瑟发抖,差点因为这个放弃了),用了一个队列。
2. 最后的ans部分,我本来又写了个DFS,看了别人代码才发现原来这么简单。
3. 我的程序中点和边都标了号,应该还能省不少空间,丑代码就留给自己看吧QWQ;
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;typedef long long ll;const int maxn = 300010;const int mod = 998244353;struct edge{ int to; ll cost; edge(int t = 0, ll c = 0){ to = t; cost = c; }};struct Ans{ ll a1, a2;};int d[maxn * 2] = { 0 };int vis[maxn * 2] = { 0 };int CNT = 0;Ans ans2[maxn];vector<int> G[maxn * 2];edge es[maxn * 4];int vise[maxn * 4] = { 0 };queue<int>q;int t, n;ll bfs(){ for (int i = n + 1; i <= 2 * n; i++){ if (d[i] == 1){ q.push(i); } } ll ans = 1; while (!q.empty()){ int now = q.front(); q.pop(); vis[now] = 1; edge to; for (int i = 0; i < G[now].size(); i++){ if (!vis[es[G[now][i]].to]) to = es[G[now][i]]; } vis[to.to] = 1; ans = (ans* to.cost) % mod; for (int i = 0; i < G[to.to].size(); i++){ d[es[G[to.to][i]].to]--; d[to.to]--; if (d[es[G[to.to][i]].to] == 1) { //printf("!%d %d %d", now, to.to, es[G[to.to][i]].to); q.push(es[G[to.to][i]].to); } } } return ans;}void dfs(int u, int s, ll sum1, ll sum2, int swi){ if (vis[u] && u == s) { ans2[CNT].a1 = sum1; ans2[CNT++].a2 = sum2; } if (vis[u]) return; vis[u] = 1; for (int i = 0; i < G[u].size(); i++){ edge &e = es[G[u][i]]; int v = e.to; if (!vise[G[u][i]]){ vise[G[u][i]] = 1; if (G[u][i] & 1) vise[G[u][i] - 1] = 1; else vise[G[u][i] + 1] = 1; if (swi) dfs(v, s, (sum1*e.cost) % mod, sum2, swi ^ 1); else dfs(v, s, sum1, (sum2*e.cost) % mod, swi ^ 1); } }}int main(){ scanf("%d", &t); while (t--){ scanf("%d", &n); int cnt = 0; for (int i = 1; i <= n; i++){ int v1, v2; ll c1, c2; scanf("%d%lld%d%lld", &v1, &c1, &v2, &c2); es[cnt].to = n + v1; es[cnt].cost = c1; G[i].push_back(cnt++); es[cnt].to = i; es[cnt].cost = c1; G[n + v1].push_back(cnt++); es[cnt].to = n + v2; es[cnt].cost = c2; G[i].push_back(cnt++); es[cnt].to = i; es[cnt].cost = c2; G[v2 + n].push_back(cnt++); d[v1 + n]++; d[v2 + n]++; d[i] = 2; } //去除一度点 ll ans = bfs(); for (int i = 1; i <= n; i++){ if (!vis[i]) dfs(i, i, 1, 1, 1); } for (int i = 0; i < CNT; i++){ ans = (ans* (ans2[i].a1 + ans2[i].a2) % mod) % mod; } printf("%lld\n", ans); for (int i = 0; i <= 2 * n + 2; i++) { vis[i] = 0;````````` d[i] = 0; G[i].clear(); } for (int i = 0; i < cnt; i++){ vise[i] = 0; } CNT = 0; cnt = 0; }}
阅读全文
0 0
- 【图论】hdu6073 Matching In Multiplication
- hdu6073 Matching In Multiplication
- HDU6073-Matching In Multiplication
- HDU6073 Matching In Multiplication【拓扑】
- hdu6073 Matching In Multiplication(搜索)
- HDU6073-拓扑排序&搜索-Matching In Multiplication
- 【2017多校 #Round 4 T7】【HDU6073】Matching In Multiplication
- 2017多校训练Contest4: 1007 Matching In Multiplication hdu6073
- Matching In Multiplication HDU
- HDU 6073 Matching In Multiplication
- HDU 6073 Matching In Multiplication
- HDU-6073 Matching In Multiplication
- hdu 6073 Matching In Multiplication
- hdu 6073 Matching In Multiplication [dfs]
- HDU 6073 Matching In Multiplication(机智)
- Matching In Multiplication(HDU 6073)
- HDU 6073 Matching In Multiplication(强连通+拓扑)
- HDU-6073 Matching In Multiplication(拓扑+dfs)
- Lightoj 1132 Summing up Powers(矩阵快速幂)
- 3Sum
- spring配置quartz入门案例
- Zero_is_start
- 3Sum Closest
- 【图论】hdu6073 Matching In Multiplication
- 指针的学习
- python 编写规范 pep8 的问题摘录
- 内存对齐、内存补齐
- Redis实现分布式锁
- 编程实现快速排序
- pyqt5在QT Designer中自定义插件
- 算法-从尾到头打印链表
- Java8 Stream排序