P3916 图的遍历

题目描述
给出N个点,MM条边的有向图,对于每个点v,求A(v)表示从点v出发,能到达的编号最大的点。

输入格式
第1 行,2 个整数N,M。

接下来MM行,每行2个整数Ui,Vi ,表示边(Ui,Vi)。
点用1, 2,…,N编号。

输出格式
N 个整数A(1),A(2),…,A(N)。
输入输出样例
输入 #1

4 3
1 2
2 4
4 3

输出 #1

4 4 3 4

思路

这道题是找每个点所能到达的最大编号,利用反向键边的思想,由大到小遍历,一旦找到就一定是最大编号,可以减少递归次数。

代码

//找每个点所能到达的最大编号 
#include<bits/stdc++.h>
using namespace std;

vector<int> vec[100001];//邻接表
int n,m; 
int giant[100001];//存每个节点可达的最大节点 

void dfs(int v,int x){
	if(giant[v]) //已经找到 则退出 
		return;
		
	giant[v]=x; 
		
	for(int i=0;i<vec[v].size();i++){
		dfs(vec[v][i],giant[v]);//对相邻点搜索 
	}
	
}

int main()
{
	int v1,v2;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>v1>>v2;
		vec[v2].push_back(v1);//反向建边  
	}
	//反向建边优点是:递归由大向小,减少搜索次数 
	//若已找到giant,则一定是最大点,因为是由小到大遍历 
		
	for(int i=n;i>=1;i--){
		dfs(i,i);
	} 
	
	for(int i=1;i<=n;i++){
		cout<<giant[i]<<" ";
	}
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<stdio.h> #include<stdlib.h> #include<conio.h> #include<math.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define NULL 0 #define MAX 20 typedef int Status; typedef struct Node {int elem; struct Node *next; }Node,*QNode; typedef struct {QNode front; QNode rear; }Queue; typedef struct ArcNode /*头节点*/ {int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边*/ }ArcNode; typedef struct VNode /*表节点*/ {int data; /*顶点信息*/ ArcNode *firstarc; /*指向第一条依附该节点的边的指针*/ }VNode,AdjList[MAX]; typedef struct {AdjList vertices; /*表节点*/ int vexnum; /*节点的个数*/ int arcnum; /*边的条数*/ }Graph; Status InitQueue(Queue *Q) {Q->front=Q->rear=(QNode)malloc(sizeof(Node)); if(!Q->front) exit(OVERFLOW); Q->front->next=NULL; return OK; } Status EnQueue(Queue *Q,int e) {QNode p=(QNode)malloc(sizeof(Node)); if(!p) exit(OVERFLOW); p->elem=e; p->next=NULL; Q->rear->next=p; Q->rear=p; return OK; } Status DeQueue(Queue *Q,int *e) {QNode p; p=Q->front->next; Q->front->next=p->next; if(Q->rear==p) Q->rear=Q->front; *e=p->elem; free(p); return OK; } Status QueueEmpty(Queue Q) {if(Q.rear==Q.front) return TRUE; else return FALSE; } int LocateVex(Graph *G,int v) /*返回节点v在中的位置*/ {int i; for(i=0;i<G->vexnum;++i) if(G->vertices[i].data==v) break; else continue; if(i<G->vexnum) return i; else return -1; } Status CreateGraph(Graph *G)/*以邻接表形式创建无向连通G*/ {int m,n,i,j,k,v1,v2,flag=0; ArcNode *p1,*q1,*p,*q; printf("Please input the number of VNode: "); scanf("%d",&m); printf("Please input the number of ArcNode: "); scanf("%d",&n); G->vexnum=m; /*顶点数目*/ G->arcnum=n; /*边的数目*/ for(i=0;i<G->vexnum;++i) {G->vertices[i].data=i+1; /*顶点信息*/ G->vertices[i].firstarc=NULL; } printf("Output the message of VNode:\n"); for(i=0;i<G->vexnum;++i) printf("v%d\n",G->vertices[i].data); for(k=0;k<G->arcnum;++k) {printf("Please input the %d edge beginpoint and endpoint: ",k+1); scanf("%d%d",&v1;,&v2;); i=LocateVex(G,v1); j=LocateVex(G,v2); if(i>=0&&j>=0) {++flag; p=(ArcNode *)malloc(sizeof(ArcNode)); p->adjvex=j; p->nextarc=NULL; if(!G->vertices[i].firstarc) G->vertices[i].firstarc=p; else{for(p1=G->vertices[i].firstarc;p1->nextarc;p1=p1->nextarc); p1->nextarc=p; } q=(ArcNode *)malloc(sizeof(ArcNode)); q->adjvex=i; q->nextarc=NULL; if(!G->vertices[j].firstarc) G->vertices[j].firstarc=q; else{for(q1=G->vertices[j].firstarc;q1->nextarc;q1=q1->nextarc); q1->nextarc=q; } } else{printf("Not hava this edge!\n"); k=flag; } } printf("The Adjacency List is:\n"); /*输出邻接表*/ for(i=0;i<G->vexnum;++i) {printf("\t%d v%d->",i,G->vertices[i].data); p=G->vertices[i].firstarc; while(p->nextarc) {printf("%d->",p->adjvex); p=p->nextarc; } printf("%d\n",p->adjvex); } return OK; } int FirstAdjVex(Graph G,int v)/*返回v的第一个邻接顶点*/ {if(G.vertices[v].firstarc) return G.vertices[v].firstarc->adjvex; else return -1; }/*FirstAdjVex*/ int NextAdjVex(Graph G,int v,int w)/*返回v中相对于w的下一个邻接顶点*/ {int flag=0; ArcNode *p; p=G.vertices[v].firstarc; while(p) { if(p->adjvex==w) { flag=1; break; } p=p->nextarc; } if(flag && p->nextarc) return p->nextarc->adjvex; else return -1; }/*NextAdjVex*/ int Visited[MAX]; void DFS(Graph G,int v)/*深度优先遍历*/ {int w; Visited[v]=TRUE; printf("v%d ",G.vertices[v].data); for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!Visited[w]) DFS(G,w); } void DFSTraverse(Graph G) {int v; for(v=0;v<G.vexnum;++v) Visited[v]=FALSE; for(v=0;v<G.vexnum;++v) if(!Visited[v]) DFS(G,v); } void BFSTraverse(Graph G)/*广度优先遍历*/ {int v,v1,w; Queue q; for(v=0;v<G.vexnum;++v) Visited[v]=FALSE; InitQueue(&q); for(v=0;v<G.vexnum;++v) if(!Visited[v]) {Visited[v]=TRUE; printf("v%d ",G.vertices[v].data); EnQueue(&q,v); /*第一个顶点入队*/ while(!QueueEmpty(q)) {DeQueue(&q,&v1;); /*第一个顶点出对*/ for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,w)) if(!Visited[w]){Visited[w]=TRUE; printf("v%d ",G.vertices[w].data); EnQueue(&q,w); }/*if*/ } } } main() {Graph G; char ch; system("cls"); CreateGraph(&G); while(1) {printf("which one choice you want DFS(1) BFS(2) orQuit(0)?\n"); scanf("%d",&ch;); switch(ch) {case 1:printf("Depth First Search:\n"); DFSTraverse(G); break; case 2:printf("\nBreadth First Search:\n"); BFSTraverse(G); break; case 0:exit(0); } } getch(); }
void CreateGraph Graph graph 的创建 { ENode p q e; int i; cout<<"请输入连通无向的顶点数和边数 例如 3 3: n"; scanf "%d %d" &graph >numberOfVerts &graph >numberOfEerts ; for i 1;i< graph >numberOfVerts;i++ { cout<<"请输入第"<<i<<"个顶点的信息: n"; cin>>graph >amlist [i] data; graph >amlist [i] number i; graph >amlist[i] firstedge NULL; graph >amlist [i] mark 0; } for i 1;i< graph >numberOfEerts;i++ { p ENode malloc sizeof ENode ; cout<<"请输入每条边的信息(编号小的在前 例如1 3回车1 2回车2 3) n"; cin>>p >ivex>>p >jvex; p >ilink p >jlink NULL; if graph >amlist [p >ivex ] firstedge NULL graph >amlist [p >ivex ] firstedge p; else { q graph >amlist [p >ivex ] firstedge ; while q NULL { e q; if q >ivex p >ivex q q >ilink ; else q q >jlink ; } if e >ivex p >ivex e >ilink p; else e >jlink p; } if graph >amlist [p >jvex ] firstedge NULL graph >amlist [p >jvex ] firstedge p; else { q graph >amlist [p >jvex ] firstedge ; while q NULL { e q; if q >ivex p >ivex q q >ilink ; else q q >jlink ; } if e >ivex p >ivex e >ilink p; else e >jlink p; } } } void SetMark Graph graph 设置访问标记 { int i; for i 1;i< graph >numberOfVerts ;i++ graph >amlist [i] mark 0; } void DFS Graph graph int v 深度遍历 { ENode p; cout<<v<<" "; graph >amlist [v] mark 1; p graph >amlist [v] firstedge ; while p NULL { if p >ivex v { if graph >amlist [p >jvex ] mark 0 { cout<<"<"<<p >ivex<<" "<<p >jvex<<">"<<endl; DFS graph p >jvex ; } p p >ilink ; } else { if graph >amlist [p >ivex] mark 0 { cout<<"<"<<p >jvex<<" "<<p >ivex<<">"<<endl; DFS graph p >ivex ; } p p >jlink ; } } }">void CreateGraph Graph graph 的创建 { ENode p q e; int i; cout<<"请输入连通无向的顶点数和边数 例如 3 3: n"; scanf "%d %d" &graph >numberOfVerts &graph >numberOfEerts ; for i 1;i< graph >numberOfVerts;i++ { cou [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值