HDU 6073 Matching In Multiplication(拓扑排序)

Matching In Multiplication

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

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.然后对于每一种完美匹配,算出边权值的乘积,然后再将每一种匹配的乘积加起来,输出最后结果。

【分析】U集合里的点 度数都为二,V集合里的点度数未知,但加起来肯定为2*n,对于V集合里度数为1的点,它的匹配对象是固定的,所以我们用拓扑排序将度数为1的点全部挖出,算出乘积res。然后对于剩下 的图,假设总节点为2*m,则V集合总度数为2*m,由于此时V集合里已经,没有度数为1的点,所以V集合里点的度数都为2,这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。比如对于两个联通块,他俩的两种方案乘积分别是(a1,a2),(b1,b2),则答案为a1*b1+a1*b2+a2*b1+a2*b2,化简后为(a1+a2)*(b1+b2),最后在乘以res即可。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define qwer 2e18
using namespace std;
typedef long long ll;
const int N = 6e5+50;
const int M = 16000009;
const int mod = 998244353;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,s;
int vis[N],in[N];
ll ans[2];
vector<pii>edg[N];
ll topSort(){
    queue<int>q;
    ll ret=1;
    for(int i=n+1;i<=n+n;i++){
        if(in[i]==1){
            q.push(i);
            vis[i]=1;
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=0;i<edg[u].size();i++){
            int v=edg[u][i].first;
            if(vis[v])continue;
            if((--in[v])==1)q.push(v),vis[v]=1;
            if(u>n)ret=(ret*1LL*edg[u][i].second)%mod;
        }
    }
    return ret;
}
void dfs(int u,int ty,int fa){
    vis[u]=1;
    for(int i=0;i<edg[u].size();i++){
        int v=edg[u][i].first;
        if(v==s&&v!=fa)ans[ty]=(ans[ty]*1LL*edg[u][i].second)%mod;
        if(vis[v])continue;
        ans[ty]=(ans[ty]*1LL*edg[u][i].second)%mod;
        dfs(v,ty^1,u);
    }
}
int main(){
    //freopen("de.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<N;i++)vis[i]=in[i]=0,edg[i].clear();
        for(int i=1,v1,w1,v2,w2;i<=n;i++){
            scanf("%d%d%d%d",&v1,&w1,&v2,&w2);
            v1+=n;v2+=n;
            edg[i].pb(mp(v1,w1));
            edg[v1].pb(mp(i,w1));
            edg[i].pb(mp(v2,w2));
            edg[v2].pb(mp(i,w2));
            in[i]+=2;
            in[v1]++;in[v2]++;
        }
        ll anss=topSort();
        for(s=1;s<=n;s++){
            if(!vis[s]){
                ans[0]=ans[1]=1;
                dfs(s,0,0);
                anss=anss*((ans[0]+ans[1])%mod)%mod;
            }
        }
        printf("%lld\n",anss);
    }
    return 0;
}
时间: 2024-08-10 17:18:07

HDU 6073 Matching In Multiplication(拓扑排序)的相关文章

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

Matching In Multiplication Problem DescriptionIn 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

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 (Java/Others)Total Submission(s): 1389    Accepted Submission(s): 423 Problem Description In the mathematical discipline of graph theory, a bipartite g

HDU 3213 Box Relations(拓扑排序构造)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3231 题意:有n个长方体,四种限制条件.(1)I x y x和y有相交:(2)X/Y/Z  x y x的最大X/Y/Z坐标小于y的最大X/Y/Z.构造出这样的n个长方体. 思路:首先,XYZ三个方向是可以分开考 虑的.那么我们可以一个个分别求解.将每个长方体拆成左上角右下角两个点,我们假设现在考虑X方向,也即是一个长方体对应两个X方向的点,共2*n个点, 边<i,j>表示i小于j,那么首先有边&l

HDU 2647 Reward(图论-拓扑排序)

Reward Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. The workers will compare their rewards ,a

HDU 2467 Reward(逆拓扑排序)

拓扑排序的变形,逆序建图就好了 Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3951    Accepted Submission(s): 1203 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival

HDU 4324 Triangle LOVE (拓扑排序)

Triangle LOVE Problem Description Recently, scientists find that there is love between any of two people. For example, between A and B, if A don't love B, then B must love A, vice versa. And there is no possibility that two people love each other, wh

HDU[1285]确定比赛名次 拓扑排序

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 题目大意:某人知道N个队伍M场比赛的胜负结果,要求输出N个队伍的名次(id为第二关键字). 核心思想:转化为图论问题,进行拓扑排序.步骤1.选定入度为0的点 2.删除该点与关联边 3.重复该过程 代码如下: //拓扑排序 (1.选入度为0的点.2.删除该点及关联边 3.重复该过程) #include <iostream> #include <memory.h> using nam

Hdu 3231 Box Relations(拓扑排序)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3231 思路:拓扑排序.将每个长方体的每对面看成一条线段,将线段看成两个点,则共有3条线段,6个点. 对于一组相交关系,若两个长方体相交,当且仅当每一维中一个长方体的面插入另一个长方体的内部. 将长方体分为左右,上下,前后三维. 例如一长方形设左面为x,右面为x+n,另一长方体左面为y,右面为y+n,则在该维中坐标x<y+n,y<x+n,x<x+n,其他两维同理. 则由大小关系,分别对每一维拓

hdu 5098 Smart Software Installer 拓扑排序or记忆化搜索

Smart Software Installer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 416    Accepted Submission(s): 124 Problem Description The software installation is becoming more and more complex. An a