题意: 给出一个二部图,U、V分别是二部图的两个点集,其中,U中每个点会有两条边连到V中两个不同的点。

  完美匹配定义为:所有点都成功匹配。

  思路:已知一定是完美匹配了呀(也一定存在),我们先把度数为一的匹配了(用拓扑把度数为一的找出来),那么剩下的图中左右各有m个点,每个点度数都不小于2,且左边每个点度数都是2,而右侧总度数是2m,因此右侧只能是每个点度数都是2。这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。

   然后就完了(还是看了别人的才懂得ε=ε=ε=┏(゜ロ゜;)┛)。
/*  gyt
Live up to every day */
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 6e5+;
const int maxm=+;
const ll mod = ;
const int INF = 0x3f3f3f;
const db eps = 1e-;
struct node {
ll w;
int v, next;
}edge[maxn<<];
int no, head[maxn];
int bad[maxn], deg[maxn], vis[maxn];
int n, nn;
queue<int>q;
vector<int>vtt;
ll ans, must; void init() {
no=;
memset(vis, , sizeof(vis));
memset(head, -, sizeof(head));
memset(bad, , sizeof(bad));
memset(deg, , sizeof(deg));
}
void add(int u, int v, int w) {
edge[no].v=v; edge[no].next=head[u];
edge[no].w=w; head[u]=no++;
}
ll dfs(int cur, int father) {
vtt.push_back(cur);
vis[cur] = ;
for(int k = head[cur], kk; k != -; k = edge[k].next) {
int v = edge[k].v;
if(v == father) continue;
if(bad[v] || vis[v]) continue;
vis[v] = ; vtt.push_back(v);
for(kk = head[v]; kk != -; kk = edge[kk].next) {
if(!bad[edge[kk].v] && edge[kk].w != cur)
break;
}
return dfs(edge[kk].v, v)*edge[k].w%mod;
}
return ;
}
void solve() {
init(); scanf("%d", &n);
nn=n*;
for (int i=; i<=n; i++) {
int v, w; scanf("%d%d", &v, &w);
add(i, n+v, w); add(n+v, i, w);
deg[i]++, deg[n+v]++;
scanf("%d%d", &v, &w);
add(i, n+v, w); add(n+v, i, w);
deg[i]++, deg[n+v]++;
}
must=;
while(!q.empty()) q.pop();
for (int i=; i<=n; i++) {
if (deg[n+i]==) q.push(n+i); //把度数为一的提出来
}
while(!q.empty()) {
int u=q.front(); q.pop();
bad[u]=;
for (int k=head[u]; ~k; k=edge[k].next) { //找到度数为一的点连的另一个点a
int v=edge[k].v;
if (bad[v]) continue;
must=must*edge[k].w%mod;
bad[v]=;
for (int kk=head[v]; ~kk; kk=edge[kk].next) {//把a相连的点找出来,如果减掉1还是1,说明他能匹配的也只能是一个
if (bad[edge[kk].v]) continue;if (--deg[edge[kk].v]==) {
q.push(edge[kk].v);
}
}
}
}
ans=must;
//cout<<ans<<endl;
for (int i=; i<=n; i++) {
if (vis[i]||bad[i]) continue;
ll ans1=;
for(int k = head[i], kk; k != -; k = edge[k].next) {//分别两种匹配的结果
int v=edge[k].v;
vtt.clear();
vis[v]=;
for ( kk=head[v]; ~kk; kk=edge[kk].next) {
if (!bad[edge[kk].v] && edge[kk].v!=i) break;
}
ans1=(ans1+dfs(edge[kk].v, v)*edge[k].w%mod)%mod;
// cout<<ans1<<endl;
vis[v]=;
for (int j=; j<vtt.size(); j++) {
vis[vtt[j]]=;
}
vtt.push_back(v);
}
for (int j=; j<vtt.size(); j++) {
vis[vtt[j]]=;
}
ans = ans*ans1%mod;
}
printf("%lld\n", ans);
}
int main() {
int t = ;
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &t);
while(t--)
solve();
return ;
}
 

hdu 6073的更多相关文章

  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(拓扑排序+思维)

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

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

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

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

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

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

  6. 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 ( ...

  7. hdu some problems in Multi-University Training Contest

    hdu 6103 Kirinriki #include<bits/stdc++.h> using namespace std; int n,m,ans; ]; void doit(int ...

  8. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

随机推荐

  1. es快照定时备份脚本

    #!/bin/bashdata1=`date "+%Y%m%d"`data2="http://0.0.0.0:9200/_snapshot/my_backup/snaps ...

  2. centos 6.9 NTP基准时间服务器配置

    时间服务器端 yum install ntp -y vim /etc/ntp.conf 增加允许客户端访问 restrict 192.168.0.0 mask 255.255.0.0 nomodify ...

  3. Linux服务器安装配置Nginx服务器

      Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务 ...

  4. f5 V11 TMSH命令行操作手册

    1.命令行登录工具:“SshClient.exe” 2.查看当前系统配置: # show running-config # show running-config net interface:网络接口 ...

  5. django的model操作整理

    单表操作 增加数据 auther_obj = {"auther_name":"崔皓然","auther_age":1} models.aut ...

  6. ATM取款机系统代码及此次作业感受

    本次乃我们软件工程专业开学第一个小测试,本来以为是和之前2016级相同的或者类似得软件,所以之前学了好久的那个程序完全失去了它的作用,当然了老师也从来没有按套路出过牌,所以这个下马威我觉得作用起到了. ...

  7. 6-完美解决Error:SSL peer shut down incorrectly

    转载自: 完美解决Error:SSL peer shut down incorrectly 打开gradle文件夹下的gradle-wrapper文件 修改其中的配置文件将红色区域修改为http:// ...

  8. C#的格式化(进制转换|位运算)

    1.首先做一下知识的普及C或c Currency 货币格式D或d Decimal 十进制格式E或e Exponent 指数格式F或f Fixed point (float)固定精度格式G或g Gene ...

  9. vue2.0跨域携带cookie和IE兼容

    /*vue-resource为了跨域获取到cookie做的操作*/ 1vue-resource跨域问题Vue.http.interceptors.push(function(request, next ...

  10. hdu 5532 (LIS) Almost Sorted Array

    http://acm.hdu.edu.cn/showproblem.php?pid=5532 题意大致是一组数中去掉一个数后问剩下的数是否构成非严格单调序列 正反各跑一遍最长非严格连续子序列,存在长度 ...