HDU 6073 Matching In Multiplication(强连通+拓扑)
来源:互联网 发布:win32编程视频教程 编辑:程序博客网 时间:2024/05/17 03:17
思路:
先找右边节点入度为1的点,设为b,所以这个点连的边一定做出了贡献。然后找左边连这个点b的点a。
将a所连的点的入度都减减,如果出现入度为1的,那么接着从这个点搜。
直到没有这样的点。
所以剩下的点都在环里。
跑一边tarjan,然后在各自的联通分量内跑一圈,注意:环的贡献由两部分组成,因为是选一条边不选一条边,所以反过来就又有一种。
#include<stdio.h>#include<string.h>#include<math.h>#include <queue>#include<algorithm>#define eps 1e-8typedef long long int lli;using namespace std;const int maxn = 650000;const int mod = 998244353;struct edge{ int to,v,next;}ed[maxn*10];int head[maxn],cnte;void ae(int x,int y,int v){ ed[++cnte].to = y; ed[cnte].v = v; ed[cnte].next = head[x]; head[x] = cnte;}lli dfn[maxn],low[maxn],stak[maxn],belong[maxn],cntc,cnts,index;bool vis[maxn];int vc[maxn];void dfs(lli u,lli f){ dfn[u] = low[u] = ++index; stak[cnts++] = u; vis[u] = 1; for(lli i = head[u];~i;i=ed[i].next){ lli v = ed[i].to; if(v == f) continue; if(!dfn[v]){ dfs(v,u); low[u] = min(low[u],low[v]); } else if(vis[v]) low[u] = min(low[u],dfn[v]); } if(dfn[u] == low[u]){ cntc++;lli v;int cnt =0; do{ cnt++; v = stak[--cnts]; vis[v] = 0; belong[v] = cntc; }while(v!=u); if(cnt == 1) vc[u] = 2; }}int n;void tarjan(){ for(int i = 1;i <= n;i++){ if(!dfn[i]) dfs(i,-1); }}bool v[maxn];void df(int p,lli &ta1,lli &ta2,int fl){ for(int i = head[p];~i;i=ed[i].next){ int to = ed[i].to; if(v[to]==0 && belong[to]==belong[p]){ v[to] = 1; if(fl == 1) ta1 = ta1*(lli)ed[i].v%mod; else ta2 = ta2*(lli)ed[i].v%mod; df(to,ta1,ta2,-fl); } }}int in[maxn];void ini(){ memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(vc,0,sizeof(vc)); memset(v,0,sizeof(v)); memset(in,0,sizeof(in)); cnte = cntc = cnts = index = 0;}int main(){ int t; scanf("%d",&t); while(t--){ ini(); scanf("%d",&n); int t1,t2,t3,t4; for(int i = 1;i <= n;i++){ scanf("%d%d%d%d",&t1,&t2,&t3,&t4); ae(i,n+t1,t2);ae(t1+n,i,t2); ae(i,n+t3,t4);ae(t3+n,i,t4); in[t1+n]++;in[t3+n]++; } tarjan(); lli ans = 1,tans1,tans2;tans1 = 1; queue<int> q;int now; for(int i = n+1;i <= n+n;i++){ if(in[i] == 1){ q.push(i); } } while(!q.empty()){ now = q.front();q.pop(); int to,va; for(int i = head[now];~i;i=ed[i].next){ int des = ed[i].to; if(!v[des]){ to = des,va = ed[i].v;break; } } ans = ans*(lli)va%mod;v[to] = 1; for(int i = head[to];~i;i=ed[i].next){ int v2 = ed[i].to; in[v2]--; if(in[v2]==1) q.push(v2); } } for(int i = 1;i <= n;i++){ if(!vc[i]&&!v[i]){ tans1 = tans2 = 1; vc[i] = 1; df(i,tans1,tans2,1); ans = ans*((tans1+tans2)%mod) % mod; } } printf("%lld\n",(ans%mod+mod)%mod); } return 0;}
阅读全文
1 0
- HDU 6073 Matching In Multiplication(强连通+拓扑)
- HDU-6073 Matching In Multiplication(拓扑+dfs)
- HDU 6073 Matching In Multiplication 思维(拓扑)
- HDU 6073 Matching In Multiplication(拓扑+思维)
- 【多校训练】hdu 6073 Matching In Multiplication. 拓扑+dfs
- HDU 6073 Matching In Multiplication(机智)
- Matching In Multiplication(HDU 6073)
- HDU 6073 Matching In Multiplication (拓扑+DFS, 2017 Multi-Univ Training Contest 4)
- HDU 6073 Matching In Multiplication
- HDU 6073 Matching In Multiplication
- HDU-6073 Matching In Multiplication
- hdu 6073 Matching In Multiplication
- HDU6073 Matching In Multiplication【拓扑】
- Matching In Multiplication HDU
- 2017多校第4场 HDU 6073 Matching In Multiplication 拓扑排序,思维,DFS
- HDU 6073 Matching In Multiplication (拓扑排序+搜索 求二分图所有完美匹配价值和)
- 2017多校四 1007题 hdu 6073 Matching In Multiplication 拓扑排序 + 找环
- hdu 6073 Matching In Multiplication(无向图+拓扑排序+dfs找环)
- list循环改变元素的值写法
- Django生产环境搭建
- J
- adb 自动脚本
- MySql 设置外网访问
- HDU 6073 Matching In Multiplication(强连通+拓扑)
- QT学习篇(三)总结界面设计相关类
- IO操作时,系统为什么不会将字符与汉字搞错
- recycle的加载更多以及网格和列表布局的随意切换
- 无监督︱异常、离群点检测 一分类——OneClassSVM
- 【mongoDB】mongoDB三秒入门笔记
- [LeetCode]647. Palindromic Substrings
- hpu暑假训练A
- 编写程序,打印出9×9乘法表