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  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 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 = 998244353;
const double eps = 1e-4;
const int N = 6e5+10;
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 = 0; i < (int)G[r].size(); i++){
        if(G[r][i].first!=f&&(vis[G[r][i].first]==0||G[r][i].first==now)){
            vis[G[r][i].first] = 1;
            if(step%2==0){
                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+1);
        }
    }
}
/*
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, 0, sizeof cnt);
        memset(vis, 0, sizeof vis);
        for(int i = 1; i <= 2*n; i++) G[i].clear();
        //input();
        for(int i = 1; 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 = 1;
        while(!q.empty()) q.pop();
        for(int i = n+1; i <= n*2; i++){
            if(cnt[i]==1){
                q.push(i);
            }
        }
        while(!q.empty()){
            int r = q.front();
            q.pop();
            int len = G[r].size();
            int pos;
            for(int i = 0; i < len; i++){
                if(vis[G[r][i].first]==0){
                    vis[G[r][i].first] = 1;
                    ans = ans*G[r][i].second%mod;
                    pos = G[r][i].first;
                    break;
                }
            }

            len = G[pos].size();
            for(int i = 0; i < len; i++){
                if(G[pos][i].first!=r){
                    cnt[G[pos][i].first]--;
                    if(cnt[G[pos][i].first]==1){
                        q.push(G[pos][i].first);
                    }
                }
            }
        }
        LL ansl, ansr;
        for(int i = 1; i <= n; i++){
            if(vis[i]==0){
                now = i;
                vis[i] = 1;
                ansl = ansr = 1;
                solve(i,-1,ansl,ansr,0);
                ans = ans*(ansl+ansr)%mod;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

相关文章:

猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-05
  • 2021-08-23
  • 2021-10-22
相关资源
相似解决方案