HDU 6073 Matching In Multiplication 思维(拓扑)
来源:互联网 发布:期货分仓软件 编辑:程序博客网 时间:2024/06/04 22:48
传送门:HDU6073
题意:给出一个二分图的两个顶点集合,每个顶点集合的大小为n,输入v1,w1,v2,w2,表示集合U中的i顶点与集合V中的v1,v2顶点相连,且边的权值为w1,w2。求两个集合的所有完备匹配的权值之和。一个完备匹配的权值为该匹配所有边的权值相乘,且数据保证至少存在一个完美匹配。
思路:官方题解说的很明白了:
首先如果一个点的度数为1,那么它的匹配方案是固定的,继而我们可以去掉这一对点。通过拓扑我们可以不断去掉所有度数为1的点。
那么剩下的图中左右各有m个点,每个点度数都不小于2,且左边每个点度数都是2,而右侧总度数是2m,因此右侧只能是每个点度数都是2。这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。
时间复杂度O(n)。
代码:#include<bits/stdc++.h>#define ll long long#define pb push_back#define fi first#define se second#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=600010;const int mod = 998244353;int gcd(int a,int b){return b?gcd(b,a%b):a;}int in[MAXN << 1];struct node{int v, w;node(){}node(int _v, int _w) : v(_v), w(_w){}}mp[MAXN * 2][10];ll ans = 0;int q[MAXN << 1];bool vis[MAXN << 1];void toposort(int n){int s = 1, t = 0;for(int i = 1; i <= n; i++)if(in[i] == 1)q[++t] = i;while(s <= t){int u = q[s++], v;for(int i = 1; i <= mp[u][0].w; i++){v = mp[u][i].v;if(vis[v]) continue;ans = (ans * mp[u][i].w) % mod;break;}vis[u] = vis[v] = 1;for(int i = 1; i <= mp[v][0].w; i++){in[mp[v][i].v]--;if(in[mp[v][i].v] == 1)q[++t] = mp[v][i].v;}}}int check(int u){for(int i = 1; i <= mp[u][0].w; i++)if(!vis[mp[u][i].v]) return mp[u][i].v;return -1;}int get(int u, int v){for(int i = 1; i <= mp[u][0].w; i++)if(mp[u][i].v == v)return mp[u][i].w;}int main(){int T, n;cin >> T;while(T--){int u, v, w, c;scanf("%d", &n);ans = 1;for(int i = 1; i <= n; i++){scanf("%d %d %d %d", &u, &w, &v, &c);in[i] += 2;in[u + n]++;in[v + n]++;mp[i][++mp[i][0].w] = node(u + n, w);mp[i][++mp[i][0].w] = node(v + n, c);mp[u + n][++mp[u + n][0].w] = node(i, w);mp[v + n][++mp[v + n][0].w] = node(i, c);}n <<= 1;toposort(n);int t;for(int i = 1; i <= n; i++){t = 1;if(vis[i]) continue;u = i;q[t] = u;vis[u] = 1;while(1){u = check(u);if(u == -1) break;q[++t] = u;vis[u] = 1;}q[t + 1] = i;//将整个环放入队列 ll x, y;x = y = 1;for(int j = 1; j <= t; j += 2)x = (x * get(q[j], q[j + 1])) % mod;for(int j = 2; j <= t; j += 2)y = (y * get(q[j], q[j + 1])) % mod;ans = (ans * (x + y)) % mod;}cout << ans << endl;for(int i = 1; i <= n + n; i++) mp[i][0].w = in[i] = vis[i] = 0;} return 0;}
阅读全文
0 0
- HDU 6073 Matching In Multiplication 思维(拓扑)
- HDU 6073 Matching In Multiplication(拓扑+思维)
- HDU 6073 Matching In Multiplication(强连通+拓扑)
- HDU-6073 Matching In Multiplication(拓扑+dfs)
- 2017多校第4场 HDU 6073 Matching In Multiplication 拓扑排序,思维,DFS
- 【多校训练】hdu 6073 Matching In Multiplication. 拓扑+dfs
- HDU 6073 Matching In Multiplication(机智)
- Matching In Multiplication(HDU 6073)
- HDU 6073 Matching In Multiplication (拓扑+DFS, 2017 Multi-Univ Training Contest 4)
- HDU 6073 Matching In Multiplication
- HDU 6073 Matching In Multiplication
- HDU-6073 Matching In Multiplication
- hdu 6073 Matching In Multiplication
- HDU6073 Matching In Multiplication【拓扑】
- Matching In Multiplication HDU
- HDU 6073 Matching In Multiplication (拓扑排序+搜索 求二分图所有完美匹配价值和)
- 2017多校四 1007题 hdu 6073 Matching In Multiplication 拓扑排序 + 找环
- hdu 6073 Matching In Multiplication(无向图+拓扑排序+dfs找环)
- 函数与消费
- Matlab投影仿真及三维曲面重构实现及演示程序
- WebRTC实时通信系列教程1 介绍
- 子类继承父类的构造方法
- undefined method 'before_filter' for Class
- HDU 6073 Matching In Multiplication 思维(拓扑)
- 单例
- 2017 暑假艾教集训 day4
- CSU-ACM2017暑期训练8-动态规划初步 C
- HDU
- 浏览器兼容
- 数据结构和算法分析之排序算法--插入排序篇(直接插入排序和希尔排序)
- tomcat安装与配置
- POJ 2528 Mayor's posters(加分割点)