hiho一下 第133周 2-SAT·hihoCoder音乐节
来源:互联网 发布:大革命1060设置优化 编辑:程序博客网 时间:2024/05/29 03:41
https://hihocoder.com/contest/hiho133/problem/1
题目1 : 2-SAT·hihoCoder音乐节
上午为真 ,下午为假
把点分成2*X,2*X+1
构图方法:
对于 a or b 的条件
转换成 ¬a->b AND ¬b->a
就是分别连两条边 ¬a->b , ¬b->a
最后对构出的图,跑强连通分量,判断 同一个点的真假如果在同一个强联通分量里,则矛盾。(即推出一首歌既要在上午播出又要在下午播出,即真假同时成立)
为什么只跑个强连通分量(tarjan)即可呢,因为原图中每一条边(a->b)的意义是 a可以推导出b
如果一个点拆成真假2x,2x+1两个点后在一个强联通里,则我们必须选一个值,不管选哪个,都会推导到真假同时成立,显然矛盾,反之,如果整个图所有拆出的点两两都不在一个强联通分量,则必然可以找出一组解.
#include<bits/stdc++.h>using namespace std;const int maxn=105*2;int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;vector<int> mp[maxn] ;stack<int>st;void add_edge(int x,bool xval,int y,bool yval){ x=x*2+xval; y=y*2+yval; mp[x^1].push_back(y); mp[y^1].push_back(x);}void dfs(int u){ pre[u]=lowlink[u]=++dfs_clock; st.push(u); for (int i=0; i<mp[u].size(); i++) { int v=mp[u][i]; if (!pre[v]) { dfs(v); lowlink[u]=min(lowlink[u],lowlink[v]); } else if (!sccno[v]) lowlink[u]=min(lowlink[u],pre[v]); } if (lowlink[u]==pre[u]) { scc_cnt++; for (;;) { int x=st.top(); st.pop(); sccno[x]=scc_cnt; if (x==u) break; } }}void find_scc(int n){ scc_cnt=dfs_clock=0; memset(pre,0,sizeof pre); memset(sccno,0,sizeof sccno); for (int i=0; i<n; i++) if (!pre[i]) dfs(i);}int main(){ int t; cin>>t; char A[100],B[100]; while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<=n*2;i++) mp[i].clear(); getchar(); for(int i=1; i<=m; i++) { scanf("%s %s",A,B); int numa=0,numb=0,lena=strlen(A),lenb=strlen(B); for(int j=1;j<lena;j++) numa=numa*10+A[j]-'0'; for(int j=1;j<lenb;j++) numb=numb*10+B[j]-'0'; numa--,numb--; if (A[0]=='m'&&B[0]=='m') add_edge(numa,1,numb,1); if (A[0]=='m'&&B[0]=='h') add_edge(numa,1,numb,0); if (A[0]=='h'&&B[0]=='h') add_edge(numa,0,numb,0); if (A[0]=='h'&&B[0]=='m') add_edge(numa,0,numb,1); } find_scc(2*n); int flag=1; for(int i=0;i<2*n;i+=2) if (sccno[i]==sccno[i+1]) flag=0; if (flag) printf("GOOD\n"); else printf("BAD\n"); } return 0;}
0 0
- hiho一下 第133周 2-SAT·hihoCoder音乐节
- HihoCoder 第133周 #1467 : 2-SAT·hihoCoder音乐节 【2-SAT】
- hihocoder #1467 : 2-SAT·hihoCoder音乐节
- hiho一下 第一百三十四周 #1468 : 2-SAT·hihoCoder新春晚会 【2-SAT 之 枚举--搜索】
- 【2-SAT】hihoCoder#1467 音乐节
- hihocoder第57周hiho一下#1196 : 高斯消元·二
- Hihocoder hiho一下 第140周 清理海报
- Hihocoder hiho一下 第141周 题目1 : 自行车架
- hihoCoder hiho一下 第148周--Font Size (模拟)
- [hihocoder]hiho一下 第163周 希尔伯特曲线
- [HiHoCoder]三分·三分求极值[hiho一下 第四十周]
- hihocoder: hiho一下 第八十八周 88
- hihocoder hiho一下 第九十五周
- hihoCoder | hiho一下144周 机会渺茫
- hihoCoder | hiho一下145周 智力竞赛
- Trie树 hiho一下第2周
- hiho一下 第143周 hiho密码
- hiho一下第一周 Hihocoder #1032 : 最长回文子串
- 解决git-gui文件数量的上限的问题
- 217. Contains Duplicate
- YOLO论文解读
- [Caffe]: 关于make runtest error
- 为什么要使用四元数
- hiho一下 第133周 2-SAT·hihoCoder音乐节
- 一天一个LINUX命令教程[2]-chattr命令
- Android 源码下载及导入
- 判断当前浏览器是不是火狐和禁止鼠标滚轮事件
- 自定义Wiew 绘制带下划线的EditText
- ASIHttprequest ARC报错
- 使用useBean或其他方式
- Cowrie蜜罐部署实践
- MySQL中timestamp数据类型的特点