標籤:sgu
題目大意:
在系統學中,Petri nets的一種特殊情況經常被納入考慮範圍,這種特殊情況被稱為Synchrograph。Synchrograph是一個有向圖,每條弧都有一個非負整數權。一個點,如果所有指向它的邊都是正數(也就是大於0),這個點就稱之為“可燃點”。
對Synchrograph的操作是一輪一輪進行的。在每一輪中,操作者都會隨機的選一個“可燃點”進行“燃燒”。所謂燃燒就是:所有指向這個點的弧權都減1,所有從這個點指出去的弧都加1。每一輪之後,“可燃點”根據新的弧權被更新,然後下一輪操作繼續進行。
如果存在一個操作序列,使得某個點變成可燃點,那麼這個點就稱之為“潛在活動點”。
如果經過任意一個操作序列之後,某個點依然是“潛在活動點”,這個點就稱之為“活動點”。
給你一個有向圖,然後要你求出哪些是活動點(1),哪些是非活動點(0)
解題思路:
由於本人太弱,所以講不清楚,直接指條明路吧:http://wenku.baidu.com/view/fe3dc1bf1a37f111f1855b5d
我也是看完了才會做的。
AC代碼:
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)>(b)?(b):(a))using namespace std;int n,m;struct bian_{int num;int elc;int next;}bian[50010]={{0,0,0}};int First[1010]={0};void Add(int p,int q,int r,int k){bian[k].num=q;bian[k].elc=r;bian[k].next=First[p];First[p]=k;return;}int du[1010]={0};int dui[1010]={0};int duip=0;int ans[1010]={0};void dfs(int k){for(int p=First[k];p!=0;p=bian[p].next){if(ans[bian[p].num]==1) continue;ans[bian[p].num]=1;dfs(bian[p].num);}return;}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int p,q,r;scanf("%d%d%d",&p,&q,&r);Add(p,q,r,i);if(r==0) du[q]++;}for(int i=1;i<=n;i++)if(du[i]==0)dui[++duip]=i;for(int i=1;i<=duip;i++){for(int p=First[dui[i]];p!=0;p=bian[p].next){if(bian[p].elc!=0) continue;du[bian[p].num]--;if(du[bian[p].num]==0)dui[++duip]=bian[p].num;}dui[i]=0;}for(int i=1;i<=n;i++)if(du[i]!=0 && ans[i]==0)dfs(i);for(int i=1;i<=n;i++)printf("%d\n",ans[i]^1);return 0; }
sgu-219 ynchrograph