hdu 6073
题意: 给出一个二部图,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的更多相关文章
- HDU 6073 - Matching In Multiplication | 2017 Multi-University Training Contest 4
/* HDU 6073 - Matching In Multiplication [ 图论 ] | 2017 Multi-University Training Contest 4 题意: 定义一张二 ...
- HDU 6073 Matching In Multiplication(拓扑排序+思维)
http://acm.hdu.edu.cn/showproblem.php?pid=6073 题意:有个二分图,左边和右边的顶点数相同,左边的顶点每个顶点度数为2.现在有个屌丝理解错了最佳完美匹配,它 ...
- 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 ...
- HDU 6073 Matching In Multiplication(拓扑排序)
Matching In Multiplication Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K ( ...
- HDU 6073 Matching In Multiplication dfs遍历环 + 拓扑
Matching In Multiplication Problem DescriptionIn the mathematical discipline of graph theory, a bipa ...
- 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 ( ...
- 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 ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
随机推荐
- numpy.random.uniform()
numpy.random.uniform均匀分布 2018年06月19日 23:28:03 徐小妹 阅读数:4238 numpy.random.uniform介绍: 1. 函数原型: numpy ...
- 缩点+出入度 poj1236
题目链接:https://vjudge.net/contest/219056#problem/H 题意:先输入n,代表接下来有n个点,接下来n行,第i行里面的数(假设是)a,b...0(到0表示结束) ...
- iOS开发时使用的bundle路径
bundle是一个目录,其中包含了程序会使用到的资源. 这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in). 对应bundle,cocoa提供了类NSBu ...
- 如何成功再次安装MYSQL
以前安过,后来再安装就是停在启动项就是过不去,无响应 弄了两天,期待奇迹,网上各种教程试了个遍就是不行,大体就是删除INI,清理注册表,以下是新的发现:(转载) 如果你的电脑里装过MySQL,想再重新 ...
- cmd乱码问题
1.进入 cmd 窗口 2.字符编码切换回中文:chcp 936 MS-DOS为以下国家和语言提供字符集: 代码页描述 1258 越南语 1257 波罗的语 1256 阿拉伯语 1255 希 ...
- ThreadLocal ——android消息机制handler在非主线程创建not called Looper.prepare() 错误的原因
引用自:https://www.jianshu.com/p/a8fa72e708d3 引出: 使用Handler的时候,其必须要跟一个Looper绑定.在UI线程可直接初始化Handler来使用.但是 ...
- HashMap从源码分析数据结构
1. HashMap在链表中存储的是键值对 2. 数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突.那么哈希冲突如何解决呢?哈希冲突的解决方案有多种:开放定址法 ...
- datepicker动态初始化
datepicker 初始化动态表单的input,需要调用jquery的on方法来给未来元素初始化. //对动态添加的时间文本框进行动态初始化 $('table').on("focus&qu ...
- C# Convert.ToInt32和int.Parse转换null和空字符串时的不同表现
Convert.ToInt32最终调用的函数见下图: int.Parse调用的函数见下图: 具体的见https://www.cnblogs.com/leolis/p/3968943.html的博客,说 ...
- C++中的npos,size_t,size_type
string类提供了6种查找函数,每种函数以不同形式find命名,这些操作全都返回string::size_type类型的值,以下标形式标记查找匹配所发生的位置,或返回一个名为string::npos ...