Matching In Multiplication

Problem Description
In the mathematical discipline of graph theory, a bipartite graph is a graph whose vertices can be divided into two disjoint sets U and V (that is, U and V are each independent sets) such that every edge connects a vertex in U to one in V. Vertex sets U and V are usually called the parts of the graph. Equivalently, a bipartite graph is a graph that does not contain any odd-length cycles. A matching in a graph is a set of edges without common vertices. A perfect matching is a matching that each vertice is covered by an edge in the set.

                       

Little Q misunderstands the definition of bipartite graph, he thinks the size of U is equal to the size of V, and for each vertex p in U, there are exactly two edges from p. Based on such weighted graph, he defines the weight of a perfect matching as the product of all the edges' weight, and the weight of a graph is the sum of all the perfect matchings' weight.

Please write a program to compute the weight of a weighted ''bipartite graph'' made by Little Q.

Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

In each test case, there is an integer n(1≤n≤300000) in the first line, denoting the size of U. The vertex in U and V are labeled by 1,2,...,n.

For the next n lines, each line contains 4 integers vi,1,wi,1,vi,2,wi,2(1≤vi,j≤n,1≤wi,j≤109), denoting there is an edge between Ui and Vvi,1, weighted wi,1, and there is another edge between Ui and Vvi,2, weighted wi,2.

It is guaranteed that each graph has at least one perfect matchings, and there are at most one edge between every pair of vertex.

Output
For each test case, print a single line containing an integer, denoting the weight of the given graph. Since the answer may be very large, please print the answer modulo 998244353.

Sample Input
1
2
2 1 1 4
1 4 2 3

Sample Output
16

题意:

  给你一个图,n点 2*n边,有边权。

  左边的1~n个点出度都为2,且都连向右边的点,两点之间,没有重边,求出每种完美匹配下各边乘积的总和

题解:

  不好好写就会wa死你哦,咕咕咕

  首先如果一个点的度数为11,那么它的匹配方案是固定的,继而我们可以去掉这一对点。通过拓扑我们可以不断去掉所有度数为11的点。

  那么剩下的图中左右各有mm个点,每个点度数都不小于22,且左边每个点度数都是22,而右侧总度数是2m2m,

  因此右侧只能是每个点度数都是22。这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。

  时间复杂度O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 1e6+, M = 1e3+,inf = 2e9; const LL mod = 998244353LL; queue<pii > q;
int vis[N],done[N],d[N],n,T,zhong;
LL ans1,ans2;
vector<pii > G[N];
void init() {
for(int i = ; i <= *n; ++i)
G[i].clear(),vis[i] = ,done[i] = ,d[i] = ;
}
void dfs(int u,int f,int p) {
vis[u] = ;
int flag = ;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i].first;
if(vis[to]) continue;
flag = ;
if(!p) ans1 = 1LL * ans1 * G[u][i].second % mod;
else ans2 = 1LL * ans2 * G[u][i].second % mod;
dfs(to,u, - p);
}
if(flag) {
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i].first;
if(to != zhong) continue;
if(!p) ans1 = 1LL * ans1 * G[u][i].second % mod;
else ans2 = 1LL * ans2 * G[u][i].second % mod;
}
}
}
void make_faiil(int u,int f,int p) {
done[u] = ;
vis[u] =;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i].first;
if(to == f || done[to]) continue;
make_faiil(to,u, - p);
}
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
init();
for(int i = ; i <= n; ++i) {
int x,y;
scanf("%d%d",&x,&y);
d[i] += ;
d[x + n] += ;
G[i].push_back(MP(x + n,y));
G[x + n].push_back(MP(i,y)); scanf("%d%d",&x,&y);
d[i] += ;
d[x + n] += ;
G[i].push_back(MP(x + n,y));
G[x + n].push_back(MP(i,y));
}
int ok = ;
while(!q.empty()) q.pop();
for(int i = n+; i <= *n; ++i) {
if(d[i] == ) {
q.push(MP(i,));
vis[i] = ;
}
}
LL ans = 1LL;
while(!q.empty()) {
pii k = q.front();
q.pop();
for(int i = ; i < G[k.first].size(); ++i) {
int to = G[k.first][i].first;
if(vis[to]) continue;
d[to] -= ;
if(d[to] == ) {
if(!k.second)ans = ans * G[k.first][i].second % mod;
q.push(MP(to,!k.second));
vis[to] = ;
}
}
}
//cout<<ans<<endl;
LL tmp1 = ans,tmp2 = ;
for(int i = ; i <= *n; ++i) {
if(!vis[i]){
// cout<<"huasndina " << i<<endl;
ans1 = 1LL,ans2 = 1LL;
zhong = i;
dfs(i,-,);
LL tmptmp = (ans1 + ans2) % mod;
ans = ans * tmptmp % mod;
}
}
printf("%lld\n",(ans)%mod);
}
return ;
} /*
10
5
1 1 2 3
1 2 3 4
3 5 4 7
3 6 4 8
4 9 5 10
4920
*/

HDU 6073 Matching In Multiplication dfs遍历环 + 拓扑的更多相关文章

  1. HDU 6073 - Matching In Multiplication | 2017 Multi-University Training Contest 4

    /* HDU 6073 - Matching In Multiplication [ 图论 ] | 2017 Multi-University Training Contest 4 题意: 定义一张二 ...

  2. HDU 6073 Matching In Multiplication(拓扑排序)

    Matching In Multiplication Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K ( ...

  3. HDU 6073 Matching In Multiplication —— 2017 Multi-University Training 4

    Matching In Multiplication Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K ( ...

  4. HDU 6073 Matching In Multiplication(拓扑排序+思维)

    http://acm.hdu.edu.cn/showproblem.php?pid=6073 题意:有个二分图,左边和右边的顶点数相同,左边的顶点每个顶点度数为2.现在有个屌丝理解错了最佳完美匹配,它 ...

  5. 2017 ACM暑期多校联合训练 - Team 4 1007 HDU 6073 Matching In Multiplication (模拟)

    题目链接 Problem Description In the mathematical discipline of graph theory, a bipartite graph is a grap ...

  6. hdu6073 Matching In Multiplication 分析+拓扑序

    Matching In Multiplication Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K ( ...

  7. 2017 多校4 Matching In Multiplication(二分图)

    Matching In Multiplication 题解: 首先如果一个点的度数为1,那么它的匹配方案是固定的,继而我们可以去掉这一对点.通过拓扑我们可以不断去掉所有度数为1的点. 那么剩下的图中左 ...

  8. HDU 1241 Oil Deposits --- 入门DFS

    HDU 1241 题目大意:给定一块油田,求其连通块的数目.上下左右斜对角相邻的@属于同一个连通块. 解题思路:对每一个@进行dfs遍历并标记访问状态,一次dfs可以访问一个连通块,最后统计数量. / ...

  9. HDU 2553(N皇后)(DFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=2553 i表示行,map[i]表示列,然后用DFS遍历回溯 可以参考这篇文章: http://blog.csdn. ...

随机推荐

  1. [转载] Laya性能优化精选内容整理

    第一是性能统计工具,这是LayaAir引擎内置的性能统计工具,在代码加入Laya.Stat.show(); 引擎内置的性能统计工具 打开这个工具后,可以用于观察性能,除了FPS越高越好外,其它的值越低 ...

  2. 【2018.2.8-】网络流学习笔记(含ISAP!)

    网络流的基础内容就不详细发了,网上到处都是,可自学. 总版点这里 ps:以下有些链接是hihocoder的题目(题面有详细讲解),请确保先登录hihocoder,再点击进入相应题目网页. 最大流 基础 ...

  3. spring 找不到applicationContext.xml解决方法

    初学Spring在用Resource rs=new ClassPathResource("applicationContext.xml");时老是遇到这个错误.后来发现用Appli ...

  4. java多线程总结一:线程的两种创建方式及比较

    1.线程的概念:线程(thread)是指一个任务从头至尾的执行流,线程提供一个运行任务的机制,对于java而言,一个程序中可以并发的执行多个线程,这些线程可以在多处理器系统上同时运行.当程序作为一个应 ...

  5. iOS7 毛玻璃效果

    转自:http://prolove10.blog.163.com/blog/static/138411843201391401054305/ 原图:  效果图:  实现:首先需要导入Accelerat ...

  6. awk 对简单文本处理试水

    #juanjuan是一个文件 [root@localhost c_test]# cat juanjuan , , bffd97d0 , , bffd97cc , , bffd97c8 , , #-F ...

  7. Java Socket应用

    Java Socket(套接字)通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求.

  8. Educational Codeforces Round 36 (Rated for Div. 2) G. Coprime Arrays

    求a_i 在 [1,k]范围内,gcd(a_1,a_2...,a_n) = 1的a的数组个数. F(x)表示gcd(a_1,a_2,...,a_n) = i的a的个数 f(x)表示gcd(a_1,a_ ...

  9. 安装 node-sass 的不成功

    昨天安装项目依赖的包,差不多都装好了,然后就卡在了node-sass上,各种报错. 报错一.gyp ERR! stack Error: Can't find Python executable &qu ...

  10. 【.Net 学习系列】-- 利用Aspose转换Excel为PDF文件

    功能: 从数据库中查询出数据 利用Aspose.cell + Excel模板绑定数据源生成Excel文件 通过Aspose.pdf + 生成好的Excel生成PDF文件 实现: 查询数据,根据Exce ...