标签:
传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1042
试题描述:
LZJ有一个问题想问问大家。他在写函数时有时候很头疼,如他写了这样几个函数:
void f1()
{
f2();
f3();
}
void f2()
{
f3();
}
void f3()
{
f1();
}
LZJ发现他无论怎么调换函数的位置,编译器总是不能通过编译,因为编译器规定调用的函数必须在当前函数之前写。
还有一种情况是这样的:
void f4()
{
f4();
}
虽然能通过编译但会无限递归。
现在LZJ想问问你,他写了一些函数,并且给你每个函数调用了哪些别的函数(可能调用本身),请问他能否通过调整函数的位置,使得编译器通过编译且不会出现无限递归?
输入:
输入第一行为一个正整数N,表示有N个函数。
接下来N行每第i行开始有一个自然数K,表示第i个函数共调用了多少别的函数(可能调用本身),接下来K个正整数vij,表示函数i调用了函数vij。
输出:
若可以输出“Yes”,否则输出“No”。
输入示例:
5
1 2
1 3
2 4 5
1 5
0
输出示例:
Yes
其他说明:
1<=N<=200,1<=K<=N, 1<=vij<=N
题解:裸有向图判环直接拓扑排序,然后如果作死可以把边搞成负的上Bellman_Ford……
然后记得判自环。
拓扑排序:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 #include <queue> 6 #define REP(s, n) for(int i = s; i <= n; i ++) 7 using namespace std; 8 const int maxn = 200 + 10; 9 const int maxm = 80000 + 10; 10 int In[maxn], n, cnt = 0; 11 int first[maxn], next[maxm], to[maxm]; 12 bool vis[maxn], TAT = true; 13 int ms = 1; 14 void AddEdge(int u, int v){ 15 next[ms] = first[u]; 16 first[u] = ms; 17 to[ms] = v; 18 In[v] ++; ms ++; 19 return ; 20 } 21 void read(int& x){ 22 x = 0; int sig = 1; char ch = getchar(); 23 while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); } 24 while(isdigit(ch)) x = 10 * x + ch -‘0‘, ch = getchar(); 25 x *= sig; return ; 26 } 27 queue<int> Q; 28 void init(){ 29 read(n); 30 int temp; 31 REP(1, n){ 32 read(cnt); 33 while(cnt --){ 34 read(temp); 35 if(temp == i) { TAT = false; return ; } 36 AddEdge(i, temp); 37 } 38 } 39 return ; 40 } 41 void work(){ 42 if(!TAT) return ; 43 REP(1, n) if(In[i] == 0) Q.push(i), vis[i] = true; 44 while(!Q.empty()){ 45 int x = Q.front(); Q.pop(); 46 for(int i = first[x]; i; i = next[i]){ 47 int& v = to[i]; 48 if(vis[v]) continue; 49 In[v] --; 50 if(In[v] == 0) Q.push(v), vis[v] = true; 51 } 52 } 53 return ; 54 } 55 void print(){ 56 if(!TAT) { puts("No"); return ;} 57 REP(1, n) if(!vis[i]) { puts("No"); return ;} 58 puts("Yes"); return ; 59 } 60 int main(){ 61 init(); 62 work(); 63 print(); 64 return 0; 65 }
Bellman_Ford:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #define INF 1000000000 6 using namespace std; 7 const int maxn=200+10,maxm=80000+10; 8 struct Tedge{int x,y,w,next;}adj[maxm];int ms=0,fch[maxn]; 9 void AddEdge(int u,int v){ 10 adj[++ms]=(Tedge){u,v,-1,fch[u]};fch[u]=ms;return; 11 } 12 int d[maxn],n; 13 bool relax(int u,int v,int w){ 14 if(d[v]>d[u]+w){d[v]=d[u]+w;return true;} 15 return false; 16 } 17 inline int read(){ 18 int x=0,sig=1;char ch=getchar(); 19 while(!isdigit(ch)){if(ch==‘-‘) sig=-1;ch=getchar();} 20 while(isdigit(ch)) x=10*x+ch-‘0‘,ch=getchar(); 21 return x*=sig; 22 } 23 inline void write(int x){ 24 if(x==0){putchar(‘0‘);return;}if(x<0) putchar(‘-‘),x=-x; 25 int len=0,buf[15];while(x) buf[len++]=x%10,x/=10; 26 for(int i=len-1;i>=0;i--) putchar(buf[i]+‘0‘);return; 27 } 28 void init(){ 29 30 } 31 bool bellman_ford(){ 32 n=read(); 33 for(int i=1;i<=n;i++) d[i]=INF; 34 for(int i=1;i<=n;i++){ 35 int k=read(); 36 for(int j=0;j<k;j++){ 37 int a=read(); 38 if(i==a) return false; 39 AddEdge(i,a); 40 } 41 } 42 bool ToT; 43 for(int i=1;i<=n;i++){ 44 ToT=false; 45 for(int i=1;i<=ms;i++){ 46 int u=adj[i].x,v=adj[i].y,w=adj[i].w; 47 if(relax(u,v,w)) ToT=true; 48 } 49 if(!ToT) break; 50 } 51 for(int i=1;i<=ms;i++){ 52 int u=adj[i].x,v=adj[i].y,w=adj[i].w; 53 if(relax(u,v,w)) return false; 54 } 55 return true; 56 } 57 void work(){ 58 if(bellman_ford()) puts("Yes"); 59 else puts("No"); 60 return; 61 } 62 void print(){ 63 return; 64 } 65 int main(){ 66 init();work();print();return 0; 67 } 68 /* 69 5 70 1 1 71 1 3 72 1 4 73 1 5 74 1 6 75 */
标签:
原文地址:http://www.cnblogs.com/chxer/p/4445438.html