图的基本存储的基本方式sdut oj

    xiaoxiao2022-07-12  157

    Problem Description

    解决图论问题,首先就要思考用什么样的方式存储图。但是小鑫却怎么也弄不明白如何存图才能有利于解决问题。你能帮他解决这个问题么? Input

    多组输入,到文件结尾。 每一组第一行有两个数n、m表示n个点,m条有向边。接下来有m行,每行两个数u、v代表u到v有一条有向边。第m+2行有一个数q代表询问次数,接下来q行每行有一个询问,输入两个数为a,b。 注意:点的编号为0~n-1,2<=n<=5000 ,n*(n-1)/2<=m<=n*(n-1),0<=q<=1000000,a!=b,输入保证没有自环和重边 Output

    对于每一条询问,输出一行。若a到b可以直接连通输出Yes,否则输出No。 Sample Input

    2 1 0 1 2 0 1 1 0 Sample Output

    Yes No 图的基本存储的基本方式一

    #include <stdio.h> #include <stdbool.h> #include <string.h> bool a[5001][5001]; int main() { int n,m,i,u,v,x,y,q; while(scanf("%d%d",&n,&m)!=EOF) { memset(a,0,sizeof(a)); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); a[u][v]=1; } scanf("%d",&q); while(q--) { scanf("%d%d",&x,&y); if(a[x][y]==1) printf("Yes\n"); else printf("No\n"); } } return 0; }

    图的基本存储的基本方式二

    #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> struct node { int data; struct node *next; }; struct node *newnode() { struct node *t; t=(struct node *)malloc(sizeof(struct node)); t->next=NULL; return t; }; int main() { int i,n,m,u,v,q,flag; while(scanf("%d%d",&n,&m)!=EOF) { struct node *num[500000],*p; for(i=0;i<n;i++) { num[i]=NULL; } for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); if(num[u]==NULL) { num[u]=newnode(); num[u]->data=v; } else { p=newnode(); p->data=v; p->next=num[u]->next; num[u]->next=p; } } scanf("%d",&q); while(q--) { flag=0;//注意flag初始化位置 scanf("%d%d",&u,&v); if(num[u]==NULL) printf("No\n"); else { p=num[u]; while(p) { if(p->data==v) { flag=1; break; } p=p->next; } if(flag==1) printf("Yes\n"); else printf("No\n"); } } } return 0; }

    图的基本存储的基本方式三 解决图论问题,首先就要思考用什么样的方式存储图。但是小鑫却怎么也弄不明白如何存图才能有利于解决问题。你能帮他解决这个问题么? Input

    多组输入,到文件结尾。 每一组第一行有两个数n、m表示n个点,m条有向边。接下来有m行,每行两个数u、v、w代表u到v有一条有向边权值为w。第m+2行有一个数q代表询问次数,接下来q行每行有一个询问,输入一个数为a 注意:点的编号为0~n-1,2<=n<=500000 ,0<=m<=500000,0<=q<=500000,u!=v,w为int型数据。输入保证没有自环和重边 Output

    对于每一条询问,输出一行两个数x,y。表示排序后第a条边是由x到y的。对于每条边来说排序规则如下: 权值小的在前。 权值相等的边出发点编号小的在前 权值和出发点相等的到达点编号小的在前 注:边的编号自0开始 Sample Input

    4 3 0 1 1 1 2 2 1 3 0 3 0 1 2 Sample Output

    1 3 0 1 1 2

    C语言 #include <stdio.h> struct node { int u,v,w; }p[500001]; void kp(int l,int r)//快排 { int i=l,j=r,m1,m2,m3; struct node m=p[i]; m1=p[i].u;m2=p[i].v;m3=p[i].w; if(i>=j) return ;//重要结束 while(i<j) { while(i<j&&((p[j].w>m3)||(p[j].w==m3&&p[j].u>m1)||(p[j].w==m3&&p[j].u==m1&&p[j].v>=m2))) j--;//题目所说的比较 p[i]=p[j]; while(i<j&&((p[i].w<m3)||(p[i].w==m3&&p[i].u<m1)||(p[i].w==m3&&p[i].u==m1&&p[i].v<=m2))) i++; p[j]=p[i]; } p[i]=m; kp(l,i-1); kp(i+1,r); } int main() { int n,m,i,q,x; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<m;i++) { scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); } kp(0,m-1); scanf("%d",&q); while(q--) { scanf("%d",&x); printf("%d %d\n",p[x].u,p[x].v); } } return 0; } C++ #include <stdio.h> #include <algorithm> using namespace std; struct node { int u,v,w; }p[500001]; int cmp(struct node &p,struct node &q) { if(p.w<q.w) return 1; else if(p.w==q.w) { if(p.u<q.u) return 1; if(p.u==q.u) { if(p.v<q.v) return 1; else return 0; } else return 0; } else return 0; } int main() { int n,m,i,q,x; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<m;i++) { scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); } sort(p,p+m,cmp);//sort排序(C++) scanf("%d",&q); while(q--) { scanf("%d",&x); printf("%d %d\n",p[x].u,p[x].v); } } return 0; }

    sort函数 使用:#include    using namespace std; 作用:排序 时间复杂度:n*lg(n) 实现原理:sort并不是简单的快速排序,它对普通的快速排序进行了优化,此外,它还结合了插入排序和推排序。系统会根据你的数据形式和数据量自动选择合适的排序方法,这并不是说它每次排序只选择一种方法,它是在一次完整排序中不同的情况选用不同方法,比如给一个数据量较大的数组排序,开始采用快速排序,分段递归,分段之后每一段的数据量达到一个较小值后它就不继续往下递归,而是选择插入排序,如果递归的太深,他会选择推排序,且sort函数默认为升序排序。 sort函数初步用法:sort(数组名(严格来说是数组的首地址),数组名加数组长度(数组尾地址的下一个地址)) 最基本有两个用法 1、降序输出、结构体排序(sort默认为升序排序,达到降序目的可以升序后逆序输出) int A[100]; bool cmp1(int a,int b)//int为数组数据类型 { return a>b;//降序排列 //return a<b;//默认的升序排列 } 2、多条件排序 原文:https://blog.csdn.net/problemlife/article/details/81559392

    图的基本存储的基本方式四 解决图论问题,首先就要思考用什么样的方式存储图。但是小鑫却怎么也弄不明白如何存图才能有利于解决问题。你能帮他解决这个问题么? Input

    多组输入,到文件结尾。 每一组第一行有一个数n表示n个点。接下来给出一个n*n的矩阵 表示一个由邻接矩阵方式存的图。 矩阵a中的元素aij如果为0表示i不可直接到j,1表示可直接到达。 之后有一个正整数q,表示询问次数。 接下来q行每行有一个询问,输入两个数为a,b。 注意:点的编号为0~n-1,2<=n<=5000,0<=q<=100,0 <= a,b < n。 保证可达边的数量不超过1000 Output

    对于每一条询问,输出一行。若a到b可以直接连通输出Yes,否则输出No。 Sample Input

    2 0 1 0 0 2 0 1 1 0 Sample Output

    Yes No

    #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> struct node { int data; struct node *next; }; struct node *newnode() { struct node *t; t=(struct node *)malloc(sizeof(struct node)); t->next=NULL; return t; }; int main() { int i,j,n,x,u,v,q,flag; while(scanf("%d",&n)!=EOF) { struct node *num[5100],*p; for(i=0; i<n; i++) { num[i]=NULL; } for(i=0; i<n; i++) { for(j=0; j<n; j++) { scanf("%d",&x); if(x==1) { if(num[i]==NULL) { num[i]=newnode(); num[i]->data=j; } else { p=newnode(); p->data=j; p->next=num[i]->next; num[i]->next=p; } } } } scanf("%d",&q); while(q--) { flag=0;//注意flag初始化位置 scanf("%d%d",&u,&v); if(num[u]==NULL) printf("No\n"); else { p=num[u]; while(p) { if(p->data==v) { flag=1; break; } p=p->next; } if(flag==1) printf("Yes\n"); else printf("No\n"); } } } return 0; } ``
    最新回复(0)