Matching In Multiplication

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 787    Accepted Submission(s): 222

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
/**
题目:hdu6073 Matching In Multiplication
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6073
题意: 思路:
首先如果一个点的度数为1,那么它的匹配方案是固定的,继而我们可以去掉这一对点。通过拓扑我们可以不断去掉所有度数为1的点。 那么剩下的图中左右各有m个点,每个点度数都不小于2,且左边每个点度数都是2,而右侧总度数是2m,因此右侧只能是每个点度数都是2。 这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。 时间复杂度O(n)。 */
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
#define lson L,m,rt<<1
typedef pair<int,int> P;
#define rson m+1,R,rt<<1|1
const int mod = ;
const double eps = 1e-;
const int N = 6e5+;
int cnt[N], vis[N];
int a[N], an, n;
LL ans;
vector<P>G[N];
queue<int> q;
int now;
void solve(int r,int f,LL &ansl,LL &ansr,int step)
{
for(int i = ; i < (int)G[r].size(); i++){
if(G[r][i].first!=f&&(vis[G[r][i].first]==||G[r][i].first==now)){
vis[G[r][i].first] = ;
if(step%==){
ansl = ansl*G[r][i].second%mod;
}else
{
ansr = ansr*G[r][i].second%mod;
}
if(G[r][i].first==now){///回到起点。
return ;
}else
return solve(G[r][i].first,r,ansl,ansr,step+);
}
}
}
/*
void input()
{
for(int i = 1; i <= n; i+=2){
G[i].push_back(P(i+n,1));
G[i].push_back(P(i+n+1,1));
G[i+1].push_back(P(i+n,1));
G[i+1].push_back(P(i+n+1,1));
G[i+n].push_back(P(i,1));
G[i+n+1].push_back(P(i,1));
G[i+n].push_back(P(1+i,1));
G[i+n+1].push_back(P(1+i,1));
cnt[i+n]+=2;
cnt[i+n+1]+=2;
}
}*/
int main()
{
//freopen("C:\\Users\\accqx\\Desktop\\in.txt","r",stdin);
int T;
cin>>T;
int u1, w1, u2, w2;
while(T--)
{
scanf("%d",&n);
memset(cnt, , sizeof cnt);
memset(vis, , sizeof vis);
for(int i = ; i <= *n; i++) G[i].clear();
//input();
for(int i = ; i <= n; i++){
scanf("%d%d%d%d",&u1,&w1,&u2,&w2);
G[i].push_back(P(u1+n,w1));
G[i].push_back(P(u2+n,w2));
G[u1+n].push_back(P(i,w1));
G[u2+n].push_back(P(i,w2));
cnt[u1+n]++;
cnt[u2+n]++;
}
ans = ;
while(!q.empty()) q.pop();
for(int i = n+; i <= n*; i++){
if(cnt[i]==){
q.push(i);
}
}
while(!q.empty()){
int r = q.front();
q.pop();
int len = G[r].size();
int pos;
for(int i = ; i < len; i++){
if(vis[G[r][i].first]==){
vis[G[r][i].first] = ;
ans = ans*G[r][i].second%mod;
pos = G[r][i].first;
break;
}
} len = G[pos].size();
for(int i = ; i < len; i++){
if(G[pos][i].first!=r){
cnt[G[pos][i].first]--;
if(cnt[G[pos][i].first]==){
q.push(G[pos][i].first);
}
}
}
}
LL ansl, ansr;
for(int i = ; i <= n; i++){
if(vis[i]==){
now = i;
vis[i] = ;
ansl = ansr = ;
solve(i,-,ansl,ansr,);
ans = ans*(ansl+ansr)%mod;
}
}
printf("%lld\n",ans);
}
return ;
}

hdu6073 Matching In Multiplication 分析+拓扑序的更多相关文章

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

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

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

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

  3. HDU 6073 Matching In Multiplication dfs遍历环 + 拓扑

    Matching In Multiplication Problem DescriptionIn the mathematical discipline of graph theory, a bipa ...

  4. [正经分析] DAG上dp两种做法的区别——拓扑序与SPFA

    在下最近刷了几道DAG图上dp的题目. 要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点. 第二道是洛谷上的NOI导刊题目<最长路 ...

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

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

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

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

  7. 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)

    3832: [Poi2014]Rally Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 168  Solved:  ...

  8. BZOJ-4010 菜肴制作 贪心+堆+(拓扑图拓扑序)

    无意做到...char哥还中途强势插入干我...然后据他所言,看了一会题,一转头,我爆了正解....可怕 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory L ...

  9. hdu5438(2015长春赛区网络赛1002)拓扑序+DFS

    题意:给出一张无向图,每个节点有各自的权值,问在点数为奇数的圈中的点的权值总和是多少. 通过拓扑序的做法标记出所有非圈上的点,做法就是加每条边的时候将两点的入度都加一,然后将所有度数为1的点入队,删去 ...

随机推荐

  1. hive的rownumber()的使用

    举个简单的栗子: 找到最小日期的那一条记录 select * from ( select *,row_number() over (partition by id order by cast(date ...

  2. Node.js nvshens图片批量下载爬虫1.01

    //====================================================== // nvshens图片批量下载爬虫1.01 // 用最近的断点续传框架改写原有1.0 ...

  3. P2P网络借贷系统-核心功能-用户投标-业务解说

    用户投标是P2P网络借贷系统的核心功能.相对照较复杂,为了更好地梳理业务和技术实现思路,特地具体总结分析下. 输入:用户id-uid.标的id-lid.投标金额-amount 1.依据lid,获得贷款 ...

  4. AutoCAD .NET二次开发(二)

    今天专门讲一个--CommandMethod.我们都在知道CAD操作要快,必须要熟悉掌握各种命令.在Lisp开发中,在函数后C:即可添加一个命令,非常方法,在.NET API也可以非常方便的设置命令, ...

  5. Android 内存泄漏分析利器——leakcanary

    LeakCanary Android 和 Java 内存泄露检测. “A small leak will sink a great ship.” - Benjamin Franklin 千里之堤, 毁 ...

  6. python——修饰符

    修饰符基础--闭包 什么是闭包呢?标准的概念大家可以看wikipedia上的解释 举个例子: def do_add(base): def add(increase): return base + in ...

  7. 微信小程序innerAudioContext接口

    voice:function(){ var word = this.data.word; var src = 'https://--/'+word['word']+'.mp3'; console.lo ...

  8. 《The Story of My Life》Introductiom - Historical and Literary Context - Education of the Deaf and Blind

    At the time the Story of My Life was published, the idea of a disabled person as an active member of ...

  9. Building Vim from source(转)

    Compiling Vim from source is actually not that difficult. Here's what you should do: First, install ...

  10. 关于 yii2 cron运行 console的脚本不运行,可是手动运行成功的原因

    在yii2中运行脚本出现了一个问题 手动运行没有问题. 在cron中不运行.最后找出来了原因 打开yii文件(在根文件夹以下) #!/usr/bin/env php <?php /** * Yi ...