Matching In Multiplication HDU

来源:互联网 发布:vb编写程序代码 编辑:程序博客网 时间:2024/06/05 02:10

https://vjudge.net/contest/176221#problem/G

题意:给出一个二分图的两个顶点集合,每个顶点集合的大小为n,输入v1,w1,v2,w2,表示集合U中的i顶点与集合V中的v1,v2顶点相连,且边的权值为w1,w2。求两个集合的所有完备匹配的权值之和。一个完备匹配的权值为该匹配所有边的权值相乘,且数据保证至少存在一个完美匹配。

#include<algorithm>#include<vector>#include<cstring>#include<string>#include<iomanip>#include<cstdio>#include<stack>#include<iostream>#include<map>#include<queue>#include<cmath>using namespace std;#define sf scanf#define pf printf#define mem(a,b) memset(a,b,sizeof(a));#define rep(i,a,b) for(int i=(a);i<=(b);++i)#define bug1 puts("bug1");#define bug2 puts("bug2");#define bug3 puts("bug3");#define N 600010#define M 1200020#define mod 998244353#define ULL unsigned long long#define LL long long#define inf 0x3f3f3f3f//2017年08月05日13:00:00LL part[2];int fst[N],du[N],vv[M],vis[N],cost[M],nxt[M],e;bool use[M];void add(int u,int v,int w ){    vv[e]=v;nxt[e]=fst[u];cost[e]=w;fst[u]=e++;}void dfs(int u,int flag){    vis[u]=1;    for(int i=fst[u];~i;i=nxt[i]){        int v=vv[i];        if(use[i])continue;        part[flag]=(part[flag]*cost[i])%mod;        use[i^1]=use[i]=true;        dfs(v,flag^1);    }}int main(){    int T ;sf("%d",&T);    while(T--){        int n;sf("%d",&n);        mem(fst,-1);e=0;        mem(du,0);mem(vis,0);mem(use,0);        rep(i,1,n){            int v1,w1,v2,w2;sf("%d%d%d%d",&v1,&w1,&v2,&w2);            add(i,v1+n,w1);add(v1+n,i,w1);            add(i,v2+n,w2);add(v2+n,i,w2);            du[v1+n]++;du[v2+n]++;            du[i]+=2;        }        queue<int>q;        for(int i=n+1;i<=2*n;++i){            if(du[i]==1){q.push(i);}        }        LL ans=1;        mem(use,false);        while(!q.empty()) {            int v=q.front();            q.pop(),vis[v]=1;            for(int i=fst[v]; ~i; i=nxt[i]) {                if(use[i])continue;                use[i]=use[i^1]=true;                vis[vv[i]]=1;                ans=(ans*cost[i])%mod;                for(int j=fst[vv[i]]; ~j; j=nxt[j]) {                    use[j]=use[j^1]=true;                    --du[vv[j]];                    if(du[vv[j]]==1)                        q.push(vv[j]);                }            }        }        for(int i=1;i<=n;++i){            part[1]=part[0]=1;            if(!vis[i]){                dfs(i,0);                ans=(ans*(part[0]+part[1])%mod)%mod;            }        }        pf("%lld\n",ans);    }}