SGU 219 Synchrograph tarjian找环,理解题意,图论 难度:3
2015-02-22 21:23
465 查看
http://acm.sgu.ru/problem.php?contest=0&problem=219
题目大意:
如果指向某个点的边权全都为正数,那么这个点就是可点燃的,点燃操作把入弧权值-1,出弧权值都+1,
如果在某种点燃序列之后还可以再点燃一些点使得这个点还可以点燃,那么这个点在这种点燃序列之后存活
如果在任何点燃序列之后都还可以再点燃一些点使得这个点还可以点燃,那么这个点可存活
现在求所有点是否可存活
思路:
考虑不可存活的点:对于某个状态,对于不可存活的点,要想使得没有序列可以使它被点燃,那么有边指向它的点里一定有不可存活的点,且这条边权值为0,
如果有一个边权值都为0的环,那么在这条环上,由于权值都为0,所以这个环上的都是不可存活的点.
所以:先通过求边权值都为0的环确定一些初始点,由这些不可存活点出发到达的点,都在某个序列下因为这些不可存活点不能提供权值而不能存活
注意:
1. 有自环
2. tarjian找环需要注意更新dfn值的点在stack内,否则对于我写的形式
会有
![](http://images.cnitblog.com/blog/660274/201502/222121393307573.png)
这种情况不正确
题目大意:
如果指向某个点的边权全都为正数,那么这个点就是可点燃的,点燃操作把入弧权值-1,出弧权值都+1,
如果在某种点燃序列之后还可以再点燃一些点使得这个点还可以点燃,那么这个点在这种点燃序列之后存活
如果在任何点燃序列之后都还可以再点燃一些点使得这个点还可以点燃,那么这个点可存活
现在求所有点是否可存活
思路:
考虑不可存活的点:对于某个状态,对于不可存活的点,要想使得没有序列可以使它被点燃,那么有边指向它的点里一定有不可存活的点,且这条边权值为0,
如果有一个边权值都为0的环,那么在这条环上,由于权值都为0,所以这个环上的都是不可存活的点.
所以:先通过求边权值都为0的环确定一些初始点,由这些不可存活点出发到达的点,都在某个序列下因为这些不可存活点不能提供权值而不能存活
注意:
1. 有自环
2. tarjian找环需要注意更新dfn值的点在stack内,否则对于我写的形式
会有
![](http://images.cnitblog.com/blog/660274/201502/222121393307573.png)
这种情况不正确
#include <cstdio> #include <stack> #include <cstring> using namespace std; const int maxn=1e3+3; const int maxm=5e4+4; int n,m; int first[maxn],head[maxn]; struct edge{ int t,nxt; }e[maxm],g[maxm]; int low[maxn],dp[maxn],depth; int alive[maxn]; bool in[maxn]; void addedge(int f,int t,int c,int ind){ if(c==0){ g[ind].nxt=head[f]; g[ind].t=t; head[f]=ind; } e[ind].nxt=first[f]; e[ind].t=t; first[f]=ind; } stack<int> st; void tarjian(int s){ low[s]=dp[s]=++depth; in[s]=true;st.push(s); for(int p=head[s];p!=-1;p=g[p].nxt){ int t=g[p].t; if(t==s){ alive[s]=0; } if(dp[t]==0){ tarjian(t); low[s]=min(low[s],low[t]); } else if(in[t]){//ATTHENTION: low[s]=min(low[s],dp[t]); } } bool single=true; if(low[s]==dp[s]){ while(st.top()!=s){ single=false; alive[st.top()]=0; in[st.top()]=false;st.pop(); } if(!single){ alive[st.top()]=0; } in[st.top()]=false;st.pop(); } } void dfs(int s){ for(int p=first[s];p!=-1;p=e[p].nxt){ int t=e[p].t; if(alive[t]==1){ alive[t]=0; dfs(t); } } } int main(){ scanf("%d%d",&n,&m); memset(first,-1,sizeof(first)); memset(head,-1,sizeof(head)); fill(alive,alive+n+1,1); for(int i=0;i<m;i++){ int f,t,c; scanf("%d%d%d",&f,&t,&c); addedge(f,t,c,i); } for(int i=1;i<=n;i++){ if(dp[i]==0){ tarjian(i); } } for(int i=1;i<=n;i++){ if(alive[i]==0){ dfs(i); } } for(int i=1;i<=n;i++){ printf("%d\n",alive[i]); } return 0; }
相关文章推荐
- SGU 219 Synchrograph tarjian找环,理解题意,图论 难度:3
- SGU 219 Synchrograph(拓扑排序)
- URAL 1557 Network Attack 图论,连通性,tarjain,dfs建树,分类讨论 难度:2
- sgu219:Synchrograph(拓扑)
- hdu 4587 tarjian求割点数目
- 深入理解计算机系统(3.7)---汇编世界当中过程的经典(十分重要)(难度较高)
- 快速切题 sgu115. Calendar 模拟 难度:0
- Song Jiang's rank list【理解题意】
- POJ 1547 Clay Bully 结构体数组使用题意理解
- ants run 题意理解
- hdu 4738 tarjian求桥
- hdoj 1034 Candy Sharing Game【基础题】&&【关键是理解题意】
- CodeForces - 739A Alyona and mex ( 思维 且题意难理解 值得重做 )
- 4879 - Old Fafhioned Typefetting 最蛋疼的一道题 题意实在是理解不了15次WA
- 深入理解计算机系统(3.8)---数组、异质结构以及指针的详解(十分重要)(难度较高)【呕心沥血版】
- sgu-219 ynchrograph
- POJ 2470 Ambiguous permutations(简单题 理解题意)
- SGU 144. Meeting 概率dp 几何概率分布 难度:0
- HDU 5934 Bomb【强联通缩点Tarjian】
- 深入理解计算机系统(3.6)---汇编中精妙的流程控制(重要)(难度较高)