hdu6073[dfs+删边] 2017多校4
题目中对二分图的定义十分特殊, 指的是 U,V两部分中,U的顶点度数必定为2,V中顶点无限制。
题目要求的是 对于所有匹配,该匹配的权值=该匹配中选中的边的边权的乘积,求所有匹配权值之和。
对于V中的顶点,a∈V , 如果a的度数为1, 那么a的最优匹配就已经决定了,此时将a对答案的贡献记录下来(ans乘上该边的权即可,因为任意一种匹配都必定包含此边)。
删去a点后,所有与a相连的顶点度数-1,如果这个时候又出现了度数为1的顶点,就重复类似a的操作,直到图中再无度数为1的顶点。
可以发现,这就是无向图判环的一种方法。剩下的顶点度数必定为2(题目中的特殊条件限制),且构成x个环。
对于每个环我们可以发现
都会只有两种取法使得最优匹配,这种跳着取边算贡献的过程我们可以用dfs实现。
题目中,一种 最优匹配的权值 是 最优匹配中所有边的乘积,所以对于一个环,我们算出 Sum蓝色=∏蓝色边 Sum红色=∏红色边
计算(Sum蓝色+Sum红色)与当前的ans相乘即可,因为任意 两个环之间的最优匹配都可以随意配对 比如 环a红色配环b蓝色, 环a蓝色配 环b蓝色...
/*hdu6073[dfs+删边] 2017多校4*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 998244353LL;
struct Edge {
int to, cost;
Edge(int T = , int C = )
: to(T), cost(C) {}
};
vector<Edge>G[];
int deg[];
bool vis[];
int T, n, u, v, w;
LL x = , y = ;
LL res = , ans = ;
void init() {
res = , ans = ;
for (int i = ; i <= * n; i++) {
G[i].clear();
}
memset(deg, , sizeof(deg));
memset(vis, , sizeof(vis));
}
void dfs(int u, int fa, int c) {
if (vis[u]) return;
vis[u] = ;
for (int i = ; i < (int)G[u].size(); i++) {
Edge &e = G[u][i];
if (e.to == fa || deg[e.to] != ) continue;
dfs(e.to, u, c ^ );
if (c) x = (x * e.cost) % MOD;
else y = (y * e.cost) % MOD;
break;
}
return;
}
void solve() {
queue<int>q;
for (int i = ; i <= * n; i++) {
if (deg[i] == ) {
q.push(i);
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
deg[u]--;
for (int i = ; i < (int)G[u].size(); i++) {
Edge &e = G[u][i];
deg[e.to]--;
if (!vis[e.to] && !vis[u]) {
vis[e.to] = vis[u] = ;
res = (res * e.cost) % MOD;
}
if (deg[e.to] == ) {
q.push(e.to);
}
}
}
memset(vis, , sizeof(vis));
for (int i = ; i <= * n; i++) {
if (deg[i] == && !vis[i]) {
x = , y = ;
dfs(i, i, );
//cout << x << ' ' << y << endl;
ans = (ans * (x + y)) % MOD;
}
}
ans = (ans * res) % MOD;
printf("%lld\n", ans);
}
int main() {
//freopen("1007.in", "r", stdin);
//freopen("1007.txt", "w", stdout);
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
init();
for (int i = ; i <= n; i++) {
scanf("%d%d", &v, &w);
G[i].push_back(Edge(v + n, w));
G[v + n].push_back(Edge(i, w));
deg[i]++, deg[v + n]++;
scanf("%d%d", &v, &w);
G[i].push_back(Edge(v + n, w));
G[v + n].push_back(Edge(i, w));
deg[i]++, deg[v + n]++;
}
solve();
}
return ;
}
hdu6073[dfs+删边] 2017多校4的更多相关文章
- hdu6035[dfs+思维] 2017多校1
/*hdu6035[dfs+思维] 2017多校1*/ //合并色块, 妙啊妙啊 #include<bits/stdc++.h> using namespace std; ; const ...
- hdu6060[贪心+dfs] 2017多校3
/* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...
- 2017 多校1 I Curse Myself
2017 多校2 I Curse Myself(第k小生成树) 题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k ...
- 2017 多校5 hdu 6093 Rikka with Number
2017 多校5 Rikka with Number(数学 + 数位dp) 题意: 统计\([L,R]\)内 有多少数字 满足在某个\(d(d>=2)\)进制下是\(d\)的全排列的 \(1 & ...
- 2017 多校5 Rikka with String
2017 多校5 Rikka with String(ac自动机+dp) 题意: Yuta has \(n\) \(01\) strings \(s_i\), and he wants to know ...
- 2017 多校4 Security Check
2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...
- hdu6038[找规律+循环节] 2017多校1
/*hdu6038[找规律+循环节] 2017多校1*/ #include<bits/stdc++.h> using namespace std; typedef long long LL ...
- hdu6074[并查集+LCA+思维] 2017多校4
看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...
- 2017 多校4 Wavel Sequence
2017 多校4 Wavel Sequence 题意: Formally, he defines a sequence \(a_1,a_2,...,a_n\) as ''wavel'' if and ...
随机推荐
- node.js0-5初级者
伴着<妈是心中的茉莉花> 这里,我用的sublime记事本,所以用的运行方法是终端.(后来发现git 可以省去cd切换目录). 安装node.js 官网说的很清楚. 这里我们可以在js文 ...
- HTML5+CSS3新增内容总结!!!!!绝对干货
说到H5C3会不会觉得东西好多啊,今天就整理了一份总结性的内容: CSS3选择器有哪些?答:属性选择器.伪类选择器.伪元素选择器.CSS3新特性有哪些?答:1.颜色:新增RGBA,HSLA模式 文字阴 ...
- SVN中trunk,branches,tags用法详解【转】
Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...
- (五)maven之外置maven
eclipse外置maven eclipse内置的maven插件是固定版本,如果要用其他版本的maven,可以使用外置maven. ① 在菜单栏上点击“Windows”à“Preferences ...
- Invalid bound statement (not found): com.ros.dao.LogMapper.insert
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.ros.dao.LogMapp ...
- Linux OpenGL 实践篇-14-多实例渲染
多实例渲染 OpenGL的多实例渲染是一种连续执行多条相同的渲染命令的方法,并且每条命令产生的结果都有轻微的差异,通常用于渲染大量的几何物体. 设想一个场景,比如太空,我们需要渲染数以万记的星球,如果 ...
- vue 不支持 数组Array,只支持get set push,但是正是做tab的时候,用到splice,就都不好用了,最后用v-if,从新渲染 完美解决
vue 不支持 数组Array,只支持get set push,但是正是做tab的时候,用到splice,就都不好用了,最后用v-if,从新渲染 完美解决
- 获取CPU相关信息
实现效果: 知识运用: WMI管理类中的ManagementObjectCollection类 ManagementObjectSearcher类的Get方法 和ManagementObje ...
- Java IO file文件的写入和读取及下载
一.FileWriter 和BufferedWriter 结合写入文件 FileWriter是字符流写入字符到文件.默认情况下,它会使用新的内容代替文件原有的所有内容,但是,当指定一个true值作为F ...
- StringMVCWeb接受前台值的几种方式
这些决定与request header 的Content-Type属性 1.通过@RequestParam @RequestParam Map<String, Object> pa ...