传送门: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……

然后记得判自环。

拓扑排序:

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#define REP(s, n) for(int i = s; i <= n; i ++)
using namespace std;
const int maxn = + ;
const int maxm = + ;
int In[maxn], n, cnt = ;
int first[maxn], next[maxm], to[maxm];
bool vis[maxn], TAT = true;
int ms = ;
void AddEdge(int u, int v){
next[ms] = first[u];
first[u] = ms;
to[ms] = v;
In[v] ++; ms ++;
return ;
}
void read(int& x){
x = ; int sig = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') sig = -; ch = getchar(); }
while(isdigit(ch)) x = * x + ch -'', ch = getchar();
x *= sig; return ;
}
queue<int> Q;
void init(){
read(n);
int temp;
REP(, n){
read(cnt);
while(cnt --){
read(temp);
if(temp == i) { TAT = false; return ; }
AddEdge(i, temp);
}
}
return ;
}
void work(){
if(!TAT) return ;
REP(, n) if(In[i] == ) Q.push(i), vis[i] = true;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = first[x]; i; i = next[i]){
int& v = to[i];
if(vis[v]) continue;
In[v] --;
if(In[v] == ) Q.push(v), vis[v] = true;
}
}
return ;
}
void print(){
if(!TAT) { puts("No"); return ;}
REP(, n) if(!vis[i]) { puts("No"); return ;}
puts("Yes"); return ;
}
int main(){
init();
work();
print();
return ;
}

Bellman_Ford:

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define INF 1000000000
using namespace std;
const int maxn=+,maxm=+;
struct Tedge{int x,y,w,next;}adj[maxm];int ms=,fch[maxn];
void AddEdge(int u,int v){
adj[++ms]=(Tedge){u,v,-,fch[u]};fch[u]=ms;return;
}
int d[maxn],n;
bool relax(int u,int v,int w){
if(d[v]>d[u]+w){d[v]=d[u]+w;return true;}
return false;
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){ }
bool bellman_ford(){
n=read();
for(int i=;i<=n;i++) d[i]=INF;
for(int i=;i<=n;i++){
int k=read();
for(int j=;j<k;j++){
int a=read();
if(i==a) return false;
AddEdge(i,a);
}
}
bool ToT;
for(int i=;i<=n;i++){
ToT=false;
for(int i=;i<=ms;i++){
int u=adj[i].x,v=adj[i].y,w=adj[i].w;
if(relax(u,v,w)) ToT=true;
}
if(!ToT) break;
}
for(int i=;i<=ms;i++){
int u=adj[i].x,v=adj[i].y,w=adj[i].w;
if(relax(u,v,w)) return false;
}
return true;
}
void work(){
if(bellman_ford()) puts("Yes");
else puts("No");
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}
/*
5
1 1
1 3
1 4
1 5
1 6
*/

Spfa:超级点向所有点引0再跑

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define inf 100000000
using namespace std;
const int maxn=+,maxm=+;
struct Tedge{int x,y,w,next;}adj[maxm];int ms=,fch[maxn];
void AddEdge(int u,int v,int w){adj[++ms]=(Tedge){u,v,w,fch[u]};fch[u]=ms;return;}
int n;
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;} if(x<) putchar('-'),x=-x;
int len=,buf[]; while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
bool inque[maxn];
int d[maxn],cnt[maxn];
bool SPFA(int S){
for(int i=;i<=n+;i++) d[i]=inf;
queue<int>Q;Q.push(S);inque[S]=true;d[S]=;
while(!Q.empty()){
int u=Q.front();Q.pop();inque[u]=false;
for(int i=fch[u];i;i=adj[i].next){
int v=adj[i].y;
if(d[v]>d[u]+adj[i].w){
d[v]=d[u]+adj[i].w;
if(!inque[v]){
if(++cnt[v]>=n+) return false;
inque[v]=true;
Q.push(v);
}
}
}
}return true;
}
void init(){
n=read();
for(int i=;i<=n;i++){
AddEdge(n+,i,);
int tp=read();
for(int j=;j<=tp;j++){
int v=read();
if(v==i){puts("No");return;}
AddEdge(i,v,-);
}
}
//for(int i=1;i<=ms;i++) printf("%d %d %d\n",adj[i].x,adj[i].y,adj[i].w);
if(SPFA(n+)) puts("Yes");
else puts("No");
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}

COJ 3012 LZJ的问题 (有向图判环)的更多相关文章

  1. Dwarves (有向图判环)

    Dwarves 时间限制: 1 Sec  内存限制: 64 MB提交: 14  解决: 4[提交][状态][讨论版] 题目描述 Once upon a time, there arose a huge ...

  2. HDU 3342 Legal or Not(有向图判环 拓扑排序)

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  3. HDU 5154 Harry and Magical Computer 有向图判环

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5154 题解: 有向图判环. 1.用dfs,正在访问的节点标记为-1,已经访问过的节点标记为1,没有访 ...

  4. CodeForces 937D 936B Sleepy Game 有向图判环,拆点,DFS

    题意: 一种游戏,2个人轮流控制棋子在一块有向图上移动,每次移动一条边,不能移动的人为输,无限循环则为平局,棋子初始位置为$S$ 现在有一个人可以同时控制两个玩家,问是否能使得第一个人必胜,并输出一个 ...

  5. POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39602   Accepted: 13 ...

  6. Codeforces Round #460 (Div. 2): D. Substring(DAG+DP+判环)

    D. Substring time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...

  7. CodeForces-1217D (拓扑排序/dfs 判环)

    题意 https://vjudge.net/problem/CodeForces-1217D 请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量. 思路 因为是有向图,每个环两 ...

  8. hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)

    这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...

  9. hdu4888 Redraw Beautiful Drawings 最大流+判环

    hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6553 ...

随机推荐

  1. 【剑指offer】二叉树中和为某一值的路径

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26141815 题目描写叙述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数 ...

  2. linux 下 apt命令集详解

    apt命令用法 packagename指代为软件包的名称 apt-get update 在修改/etc/apt/sources.list或/etc/apt/preferences之後运行该命令.此外您 ...

  3. 再回首,Java温故知新——开篇说明

    不知不觉在IT界从业2年了,两年时间足够一个人成长很多,当然也会改变很多事.在这两年时间里,随着对技术的深入了解,知识面的拓展以及工作难度的增大,渐渐的感觉自己技术方面根基不稳,多数问题也只是做到知其 ...

  4. C#读取Word文档内容代码

    首先要添加引用com组件:然后引用: using Word = Microsoft.Office.Interop.Word; 获取内容: /// /// 读取 word文档 返回内容 /// //// ...

  5. JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)

    Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制.类从被加载到虚拟机内存中开始,到卸载出内 ...

  6. linux之CentOS-7.0环境搭建

    此文作为新手安装centos-7的图文教程.  一.  前言 最近,师兄要进行实验室架构搭建,需要学习docker.而docker是完全依赖于linux系统的.所以,有了这篇文章. linux有很多发 ...

  7. win10的独立存储

    win10的独立存储和win8的大致相同 Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.Appl ...

  8. ASPNET5的依赖注入

    ASP.NET5设计的时候就是以DI为基础的,它可以利用内建的框架在Startup类的方法中,把依赖注入进去.应用服务也可以被配置的注入.默认的服务容器提供一些基本的功能,它并不打算代替现代主流的DI ...

  9. 小波 mallat 算法

    算法要求:输入序列是大于滤波器长度的偶数列 确实可以通过编程的手段使算法适合所有的情况,但本文章的目的是展示mallat算法的过程,所以就一切从简了 // Mallat.cpp : Defines t ...

  10. 【USACO 1.4.1】铺放矩形块

    [描述] 给定4个矩形块,找出一个最小的封闭矩形将这4个矩形块放入,但不得相互重叠.所谓最小矩形指该矩形面积最小.               所有4个矩形块的边都与封闭矩形的边相平行,图1示出了铺放 ...