首页 > 代码库 > UVA 11770 Lighting Away
UVA 11770 Lighting Away
RunID | User | Problem | Result | Memory | Time | Language | Length | Submit Time |
2482977 | zhyfzy | J | Accepted | 0 KB | 138 ms | C++ 4.8.2 | 2322 B | 2014-07-24 15:18:54 |
【题目大意】
一个有向图,每对一个结点操作,就可以触发连锁反应,使得该结点及它直接或间接指向的点均获得标记,问至少需要操作多少个结点使得所有结点获得标记
【题解】
缩点+DFS
首先能想到入度为0的点一定需要操作,但是操作完所有入度为0的点不一定使所有结点获得标记,比如存在环的情况,因此,我们需要先缩点,缩点使用Tarjan算法,详见代码,缩点之后直接统计入度为0的点有多少个即可。
代码采用链式向前星的存储结构
【代码】
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<stack>#define P 20000#define E 200000using namespace std;int i,j,k,n,T,ans,K,m,x,y,indexs,nn,mm;int ru[P],head[P],head2[P],dfn[P],low[P],instack[P],belong[P];bool b[E];stack <int> tar; struct node{ int from; int to; int next;}map[E],map2[E];void addedge(int num,int x,int y){ map[num].from=x; map[num].to=y; map[num].next=head[x]; head[x]=num;}void addedge2(int num,int x,int y){ //printf("NewEdge %d %d\n",x,y); ru[y]++; map2[num].from=x; map2[num].to=y; map2[num].next=head2[x]; head2[x]=num;}void dfs(int p){ for (int i=head2[p];i!=-1;i=map2[i].next) { if (!b[map2[i].to]) { b[map2[i].to]=true; dfs(map2[i].to); } }}void tarjan(int k){ int p; tar.push(k); instack[k]=1; dfn[k]=low[k]=++indexs; for(int j=head[k];j!=-1;j=map[j].next) { p=map[j].to; if (instack[p]) { low[k]=min(low[k],dfn[p]); } else if(dfn[p]==-1) { tarjan(p); low[k]=min(low[k],low[p]); } } if(low[k]==dfn[k]) { nn++; do { j=tar.top(); tar.pop(); instack[j]=0; belong[j]=nn; }while(j!=k); }}void build_new_map(){ for(int i=1;i<=m;i++) { if(belong[map[i].from]==belong[map[i].to]) continue; addedge2(++mm,belong[map[i].from],belong[map[i].to]); }}void build_map(){ scanf("%d%d",&n,&m); for (i=1;i<=m;i++) { scanf("%d%d",&x,&y); addedge(i,x,y); } memset(dfn,-1,sizeof(dfn)); memset(low,-1,sizeof(low)); memset(instack,0,sizeof(instack)); indexs=0;nn=0; for (i=1;i<=n;i++) belong[i]=i; for (i=1;i<=n;i++) { if (dfn[i]==-1) tarjan(i); } build_new_map();}int main(){ scanf("%d",&T); while (++K<=T) { memset(map,-1,sizeof(map)); memset(head,-1,sizeof(head)); memset(map2,-1,sizeof(map2)); memset(head2,-1,sizeof(head2)); memset(b,0,sizeof(b)); memset(ru,0,sizeof(ru)); ans=0;mm=0;nn=0; build_map(); for (i=1;i<=nn;i++) { if (!ru[i]) { ans++; b[i]=true; dfs(i); } } for (i=1;i<=nn;i++) { if (!b[i]) { ans++; b[i]=true; dfs(i); } } printf("Case %d: %d\n",K,ans); }}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。