题意: 给出一个二部图,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. oracle数据库连接不上

    Oracle数据库1521端口telnet不通 现象:服务器的ip地址可以ping通,但是安装oracle过程中的指定的“1521”端口telnet不通过 解决办法:1.确保防火墙对1521端口开启: ...

  2. 终端设备 tty,pty,pts 概念与文件描述符的联系

    第1节 理解终端设备tty.pty.pts概念 简要描述: 终端设备默认具有输入.输出功能. 现代我们最常用的接入服务器端的方式(如:ssh通过tcp/ip的方式连接服务器端,作为服务器的终端设备)为 ...

  3. SQL 本地数据库

      先写一个数据库帮助器: public class MyDBHelper extends SQLiteOpenHelper { private static final String DB_NAME ...

  4. Jmeter录制APP脚本

    启动 jmeter.bat 在 Test Plan 下 添加 Thread Group 在 WorkBench 下 添加 HTTP(S) Test Script Recorder: 配置 Global ...

  5. ubuntu下安装、破解securtCRT工具

    官网:https://www.vandyke.com/ 下载好的安装包以及破解工具的网盘地址:链接: https://pan.baidu.com/s/1UEKEy-aob7WdfPLR4PNJmg 提 ...

  6. 六.Spring与RabbitMQ集成--HelloWorld

    spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...

  7. ScrollView嵌套ListView,禁止ListView的滚动,只让ScrollView可以滚动

    自定义ListView,xml布局文件中使用该自定义的ListView public class NoScrollListview extends ListView{ public NoScrollL ...

  8. 41-ssm中对象查找正确但是没有将数据库中某个属性值赋给对象的一个成员变量

    原因: 变量名虽然与 数据库字段一致,但是 包含下划线,如: a_b,数据库确实也是a_b: 但是ssm开启驼峰命名了,就要将变量名改为   aB , 驼峰命名就可以了.

  9. python:在for遍历list时使用remove出现的问题以及解析(转)

    原文地址:http://blog.csdn.net/circle2015/article/details/64444300最近面试时,面试官在纸上写了几行代码,说是很简单的问题,我看后直接懵逼...如 ...

  10. C#使用MiniDump捕获异常

    c/c++语言里MiniDump是一个重要的调试手段,他们没有C#/java这样语言有很多异常输出信息( JVM异常导出bug日志功能,通常在jdk目录,文件格式hs_err_%pid%.log,pi ...