栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

P2296 [NOIP2014 提高组] 寻找道路

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

P2296 [NOIP2014 提高组] 寻找道路

目录
  • 分数
    • 估分
    • 实际分数
  • 思路
    • 代码
    • 一点想法
  • 正解
    • 错误原因
    • 正确思路
    • 正确代码

分数 估分

20 {color{Red}20} 20

实际分数

20 {color{Red}20} 20

思路 代码
#include
using namespace std;
bool a[10010][10010];
int n,m;
int be,en;
bool find_[10010];
int finddp[10010];
bool find(int x){
	if(finddp[x]!=-1) return finddp[x];
	else if(x==en) return finddp[x]=1;
	else if(find_[x]!=0) return finddp[x]=0;
	else{
		bool u=0;
		find_[x]=1;
		for(int i=1;i<=n;i++){
			if(a[x][i]==1){
				u=u||find(i);
			}
		}
		find_[x]=0;
		return u;
	}
}
int findingdp[10010];
bool finding(int x){
	if(findingdp[x]!=-1){
		if(findingdp[x]==1) return 1;
		else return 0;
	}
	else{
		bool u=1;
		for(int i=1;i<=n;i++){
			if(a[x][i]==1){
				u=u&&find(i);
			}
		}
		return u;
	}
}
int fdp[10010];
bool f_[10010];
int f(int x){
	if(fdp[x]!=0) return fdp[x];
	else if(x==en) return 0;
	else if(finding(x)==0){
		return fdp[x]=-1;
		
	}
	else if(f_[x]==1) return fdp[x]=-1;
	else{
		int u=-1;
		f_[x]=1;
		for(int i=1;i<=n;i++){
			if(a[x][i]==1){
				int j=f(i);
				if(j!=-1){
					if(u==-1) u=j;
					else if(u!=-1&&u>j) u=j; 
				}  
			}
		}
		f_[x]=0;
		if(u!=-1) return fdp[x]=u+1;
		else return -1;
	}
}
int main(){
	memset(finddp,-1,sizeof(finddp));
	memset(findingdp,-1,sizeof(finddp));
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int p,q;
		scanf("%d%d",&p,&q);
		a[p][q]=1;
	}
	scanf("%d%d",&be,&en);
	printf("%dn",f(be));
	return 0;
}
一点想法

find函数用于寻找一个点与终点是否相连
finding函数用于判断一个点是否符合路径上的点的要求
f函数用于寻找最短路
(可能的错误在于一个点是否通往终点的状态记录错误)

正解 错误原因

W r o n g   A n s w e r {color{Red}Wrongspace Answer} Wrong Answer

正确思路

因为路径上的所有点的出边所指向的点都直接或间接与终点连通,所以我们不妨把所有的边反向,然后求t到s的最短路径

正确代码
void travel(int k)
{
    h[k]=true;
    for(int i=p[k];i;i=next[k])
    if(!h[x[k]]) travel(x[k]);
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&x[i],&y[i]);
        next[i]=p[y[i]]; p[y[i]]=i;
    }
    scanf("%d %d",&s,&t);
    travel(t);
    memset(p,0,sizeof(p));
    for(int i=1;i<=m;i++) { next[i]=p[x[i]]; p[x[i]]=i; }
    memset(f,true,sizeof(f));
    for(int i=1;i<=n;i++)
        for(int j=p[i];j;j=next[j])
            if(!h[y[j]]) f[i]=false;
    memset(d,127,sizeof(d));
    memset(h,false,sizeof(h));
    if(f[s]) d[s]=0;
    list[0]=s; h[s]=true;
    while(head<=tail)
    {
        for(int i=p[list[head]];i;i=next[i])
            if(f[y[i]] && d[x[i]]+1
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302390.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号