Matching In Multiplication

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

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个顶点的集合,分别为U,V,从U的每个顶点会有连出两条带权边与V的顶点相连。题目要求我们选取若干条边,使两个集合的所有点得到覆盖,并且定义这种情况为“完美匹配“,”完美匹配“的值为所选取的边权值求积,最后输出所有完美匹配的值之和。
 
思路:首先对于V的所有点来说,入度为1的点一定在U集合有唯一的点与之相连,在每种”完美匹配“里它们的配对是固定的,于是就可以扫一遍所有唯一对应的点对,求出它们的边权之积 left。
在排除以上情况的点之后,U集合点的出度均为2,假如V集合存在入度大于2的点,必存在另外有个点入度小于2。然而这是不可能的,否则就和上一种情况矛盾。所以剩余V集合里的点入度均为2,剩余的边构成了环。接着间隔取点,每个环的”完美匹配“结果分两种s[0], s[1],求出所有s[0]+s[1], 与left相乘取模得到结果。(补题时没好好理解题意,把相乘写成相加了(/TДT)/)
 
AC代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<fstream>
#include<queue>
using namespace std;
typedef long long LL;
const int MAXN=6e5+;
const int N=3e5;
const LL MOD=;
struct Edge{
int to;
LL w;
};
vector<Edge> edge[MAXN];
int deg[MAXN];
LL s[];
void dfs(int node,int pos, bool ext){
//cout<<node<<' '<<s[0]<<' '<<s[1]<<' '<<deg[node]<<' '<<ext<<endl;
for(int i=;i<edge[node].size();i++){
int p=edge[node][i].to;
if(!deg[p])
continue; if(deg[p]==)
{
deg[node]--;
deg[p]--;
s[pos]=s[pos]*edge[node][i].w%MOD;
dfs(p, pos^, ext);
break;
}
else if(deg[node]==&&deg[p]==)
{
if(ext==false)
ext=true;
else{
deg[node]--;
deg[p]--;
s[pos]=s[pos]*edge[node][i].w%MOD;
return;
}
}
}
} int main()
{
//ifstream cin("ylq.txt");
int T;
cin>>T;
int n,v1,v2;
LL w1,w2;
Edge e1,e2;
while(T--)
{
memset(deg, , sizeof(deg));
//cin>>n;
scanf("%d", &n);
for(int i=;i<=N+n;i++){
edge[i].clear();
}
for(int i=;i<=n;i++){
//cin>>v1>>w1>>v2>>w2;
scanf("%d %lld %d %lld", &v1, &w1, &v2, &w2);
deg[v1+N]++;
deg[v2+N]++;
deg[i]+=; e1.to=v1+N;e1.w=w1;
e2.to=v2+N;e2.w=w2;
edge[i].push_back(e1);
edge[i].push_back(e2); e1.to=i;e2.to=i;
edge[v1+N].push_back(e1);
edge[v2+N].push_back(e2);
} LL left=;
queue<int> q;
for(int i=N;i<=n+N;i++)
if(deg[i]==)
q.push(i); int m;
while(!q.empty())
{
int p, pp;
m=q.front(); q.pop();
deg[m]=;
for(int i=;i<edge[m].size();i++){
p=edge[m][i].to;
if(!deg[p])
continue;
else
{
deg[p]=;
left=left*edge[m][i].w%MOD;
for(int k=;k<edge[p].size();k++){
pp=edge[p][k].to;
if(deg[pp]==) continue; deg[pp]--;
if(deg[pp]==)
q.push(pp);
}
}
} }
//cout<<'*'<<left<<'*'<<endl;
LL ans=left;
for(int i=;i<=n;i++){
if(!deg[i])
continue;
s[]=s[]=;
dfs(i, , );
ans=ans*(s[]+s[])%MOD;
} printf("%lld\n", ans);
}
}

我的代码里用入度出度判断是否走到重复点,看了好多人都是用vis判断的,感觉都差不多。。。。

 

HDU 6073 Matching In Multiplication —— 2017 Multi-University Training 4的更多相关文章

  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 dfs遍历环 + 拓扑

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

  4. 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 ...

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

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

  6. HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9

    /* HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9 题意: N节点的树,Q组询问 每次询问s,t两节 ...

  7. HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9

    /* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...

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

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

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

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

随机推荐

  1. 异常-打开文件过多(too many open files)

    异常-打开文件过多 异常报错如下 09-Oct-2019 15:37:51.923 严重 [http-nio2-8080-Acceptor-0] org.apache.tomcat.util.net. ...

  2. Selenium WebDriver UI对象库

    UI对象库:使用配置文件存储测试页面上的定位和定位表达式,做到定位数据和程序的分离. 第一步:实现工具类Object工具类,供测试程序调用. /** * 使用配置文件存储测试页面上的定位和定位表达式, ...

  3. Python 操作 mongodb 亿级数据量使用 Bloomfilter 高效率判断唯一性 例子

    工作需要使用 python 处理 mongodb 数据库两亿数据量去重复,需要在大数据量下快速判断数据是否存在 参考资料:https://segmentfault.com/q/101000000061 ...

  4. Hadoop(2): Blocks存储管理及读写

    1. Replication: 因为每个HDFS被部署在是低成本的商业硬件上(low cost commodity hardware),所以为了有更佳的Fault Tolerance,HDFS将每个B ...

  5. urllib.parse解析链接

    1. urlparse() 解析链接,注意,返回值比3多一个params的属性 from urllib.parse import urlparse result = urlparse('http:// ...

  6. JavaScript defineProperties

    function defineProperties(obj, properties) {   function convertToDescriptor(desc)   {     function h ...

  7. SR-IOV

    SR-IOV 来源 http://blog.csdn.net/liushen0916/article/details/52423507 摘要: 介绍SR-IOV 的概念.使用场景.VMware 和 K ...

  8. tensorflow用dropout解决over fitting

    在机器学习中可能会存在过拟合的问题,表现为在训练集上表现很好,但在测试集中表现不如训练集中的那么好. 图中黑色曲线是正常模型,绿色曲线就是overfitting模型.尽管绿色曲线很精确的区分了所有的训 ...

  9. Android 线程池概念及使用

    一:使用线程池的原因 在android开发中经常会使用多线程异步来处理相关任务,而如果用传统的newThread来创建一个子线程进行处理,会造成一些严重的问题: 在任务众多的情况下,系统要为每一个任务 ...

  10. ssh-agent - 认证代理

    总览 (SYNOPSIS) ssh-agent [-a bind_address ] [-c | -s ] [-t life ] [-d ] [command [args ... ] ] ssh-ag ...