http://acm.hdu.edu.cn/showproblem.php?pid=6073

题意:
有个二分图,左边和右边的顶点数相同,左边的顶点每个顶点度数为2。现在有个屌丝理解错了最佳完美匹配,它以为最佳完美匹配是边权的乘积了,现在要你计算所有这种最佳完美匹配的边权乘积和。保证至少存在一个完美匹配。

思路:

这道题目虽然打着二分图的幌子,但其实吧,根本就不是二分图,哎。

对于右边的点来说,如果它的度数为1,那么与它匹配的点肯定是确定的,所以我们先通过拓扑排序来计算出所有确定的匹配。去除这些点后,假设左边和右边各还剩下x个点,此时还有2x条边,此时右边顶点每个顶点的度数必为2。

此时其实就是连通图,对于左边的每一个顶点,它都有两种边可供选择,然而一旦确定了一条边之后,整个环就都确定下来了,所以对于一个环来说共有两种选择方法。

参考了大神的dfs方法,太强了!!!

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn=3e5+;
const int mod=; int n;
int tot, head[*maxn];
int del[*maxn], deg[maxn];
ll res[]; struct node
{
int v, w, next;
int mark;
}e[*maxn]; void addEdge(int u, int v, int w)
{
e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; e[tot].mark=;
head[u]=tot++;
} void init()
{
tot=;
memset(head,-,sizeof(head));
memset(deg,,sizeof(deg));
memset(del,,sizeof(del));
} void dfs(int u, int flag)
{
del[u]=;
for(int i=head[u];i!=-;i=e[i].next)
{
if(e[i].mark) continue;
int v=e[i].v;
e[i].mark=e[i^].mark=;
res[flag]=(res[flag]*e[i].w)%mod;
dfs(v,flag^);
}
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int v1,d1,v2,d2;
scanf("%d%d%d%d",&v1,&d1,&v2,&d2);
addEdge(i,v1+n,d1); addEdge(v1+n,i,d1);
addEdge(i,v2+n,d2); addEdge(v2+n,i,d2);
deg[v1]++; deg[v2]++;
} ll ans=;
queue<int> Q;
for(int i=;i<=n;i++)
if(deg[i]==) Q.push(i+n); while(!Q.empty())
{
int u=Q.front(); Q.pop();
del[u]=;
for(int i=head[u];i!=-;i=e[i].next) //左边
{
if(e[i].mark) continue;
int v=e[i].v;
del[v]=;
e[i].mark=e[i^].mark=;
ans=(ans*e[i].w)%mod; for(int j=head[v];j!=-;j=e[j].next) //右边
{
if(e[j].mark) continue;
int p=e[j].v;
deg[p-n]--;
e[j].mark=e[j^].mark=;
if(deg[p-n]==) Q.push(p);
}
}
} for(int i=;i<=n;i++)
{
if(!del[i])
{
res[]=res[]=;
dfs(i,);
ans=(ans*((res[]%mod+res[]%mod)%mod))%mod;
}
}
printf("%I64d\n",ans);
}
return ;
}

HDU 6073 Matching In Multiplication(拓扑排序+思维)的更多相关文章

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

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

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

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

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

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

  6. HDU.3342 Legal or Not (拓扑排序 TopSort)

    HDU.3342 Legal or Not (拓扑排序 TopSort) 题意分析 裸的拓扑排序 根据是否成环来判断是否合法 详解请移步 算法学习 拓扑排序(TopSort) 代码总览 #includ ...

  7. HDU.1285 确定比赛名次 (拓扑排序 TopSort)

    HDU.1285 确定比赛名次 (拓扑排序 TopSort) 题意分析 裸的拓扑排序 详解请移步 算法学习 拓扑排序(TopSort) 只不过这道的额外要求是,输出字典序最小的那组解.那么解决方案就是 ...

  8. HDU 4857 逃生 (反向拓扑排序 & 容器实现)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  9. ACM: HDU 1285 确定比赛名次 - 拓扑排序

     HDU 1285 确定比赛名次 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u De ...

随机推荐

  1. win8 metro 自己写摄像头拍照项目

    这个项目不是用的系统自带的CameraCaptureUI.是自己写的摄像头的调用,界面做的不好所以,不放了.可是能够实现拍照功能: 以下是using 程序命名空间: using Windows.Med ...

  2. Andrew Ng-ML-第十四章-无监督学习

    1.无监督学习概述  图1.无监督学习 有监督学习中,数据是有标签的,而无监督学习中的训练集是没有标签的,比如聚类算法. 2.k-means算法 k-means算法应用是十分广泛的聚类方法,它包括两个 ...

  3. Centos上把新安装的程序添加到系统环境变量的两种方法

    1.软链接 通过命令查看当前系统的环境变量信息,然后软连接形式把程序的地址连接到已经在环境变量中的目录中 echo "$PATH" > /root/tmp 结果如下: /us ...

  4. selenium webdriver模拟鼠标键盘操作

    在测试使用Selenium webdriver测试WEB系统的时候,用到了模拟鼠标.键盘的一些输入操作. 1.鼠标的左键点击.双击.拖拽.右键点击等: 2.键盘的回车.回退.空格.ctrl.alt.s ...

  5. POST—GET—两种提交方式的区别

        主要区别: 安全性 长度限制 数据结构.   总结起来: get方式:以URL字串本身传递数据参数,在服务器端可以从UERY_STRING'这个变量中直接读取,效率较高,但缺乏安全性,也无法来 ...

  6. Data Center Drama 欧拉回路的应用

    这题说的是给了n个点 和m条边, 这m条边是无向的,任务是将这些边变成有向的,并且添加最少的有向边使得这个图中每个点的入度为偶数, 出度为偶数. 我们可以考虑使用欧拉回路来解决这个问题,这样说,假如一 ...

  7. AutoLayout 的一些坑

    1. 给一个 UIView 加约束,希望它显示在 UITableView 的底部,但是它不显示,它会出现在 UITableView 的顶部. 错误代码: [self.tableView addSubv ...

  8. MySQL中的基本SQL语句

    标准SQL包含了4种基本的语句类别: DDL语句,数据定义语句,主要用来定义数据库,表名,字段,例如create,drop,alter. DML语句,数据操作语句,用来对数据记录的增删改查,还用来保证 ...

  9. 来了解一下Ajax是什么?Ajax的原理?Ajax与传统Web比较?Ajax的优缺点?Ajax的Post与Get比较

    一.什么是Ajax Ajax(Asynchronous Java and XML的缩写)是一种异步请求数据的web开发技术,对于改善用户的体验和页面性能很有帮助.简单地说,在不需要重新刷新页面的情况下 ...

  10. P3374 【模板】树状数组 1(cdq)

    P3374 [模板]树状数组 1 cdq分治 刚学了cdq分治(dyf神犇强力安利下),发现可以做这种题,当然是来试水了(逃 cdq好像只能离线的样子 cdq分治(转) 以下是摘录的几句: 在合并的时 ...