zoukankan      html  css  js  c++  java
  • SDUST数据结构

    判断题:

     

     

     

     

     

     

     

     

     

    选择题:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    函数题:

      6-1 邻接矩阵存储图的深度优先遍历:

    裁判测试程序样例:

    #include <stdio.h>
    
    typedef enum {false, true} bool;
    #define MaxVertexNum 10  /* 最大顶点数设为10 */
    #define INFINITY 65535   /* ∞设为双字节无符号整数的最大值65535*/
    typedef int Vertex;      /* 用顶点下标表示顶点,为整型 */
    typedef int WeightType;  /* 边的权值设为整型 */
    
    typedef struct GNode *PtrToGNode;
    struct GNode{
        int Nv;  /* 顶点数 */
        int Ne;  /* 边数   */
        WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
    };
    typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
    bool Visited[MaxVertexNum]; /* 顶点的访问标记 */
    
    MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */
    
    void Visit( Vertex V )
    {
        printf(" %d", V);
    }
    
    void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
    
    
    int main()
    {
        MGraph G;
        Vertex V;
    
        G = CreateGraph();
        scanf("%d", &V);
        printf("DFS from %d:", V);
        DFS(G, V, Visit);
    
        return 0;
    }
    
    /* 你的代码将被嵌在这里 */

    代码:

    void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
    {
        Visit(V);
        Visited[V] = true;
        for(int i=0;i<Graph->Nv;i++)
        {
            if((Graph->G[V][i]==1)&&(!Visited[i]))//1代表相通,Visited非1代表没有访问过
                DFS(Graph, i, Visit);//递归
        }
    }
    View Code

      6-2 邻接表存储图的广度优先遍历:

    裁判测试程序样例:

    #include <stdio.h>
    
    typedef enum {false, true} bool;
    #define MaxVertexNum 10   /* 最大顶点数设为10 */
    typedef int Vertex;       /* 用顶点下标表示顶点,为整型 */
    
    /* 邻接点的定义 */
    typedef struct AdjVNode *PtrToAdjVNode; 
    struct AdjVNode{
        Vertex AdjV;        /* 邻接点下标 */
        PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
    };
    
    /* 顶点表头结点的定义 */
    typedef struct Vnode{
        PtrToAdjVNode FirstEdge; /* 边表头指针 */
    } AdjList[MaxVertexNum];     /* AdjList是邻接表类型 */
    
    /* 图结点的定义 */
    typedef struct GNode *PtrToGNode;
    struct GNode{  
        int Nv;     /* 顶点数 */
        int Ne;     /* 边数   */
        AdjList G;  /* 邻接表 */
    };
    typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */
    
    bool Visited[MaxVertexNum]; /* 顶点的访问标记 */
    
    LGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */
    
    void Visit( Vertex V )
    {
        printf(" %d", V);
    }
    
    void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );
    
    int main()
    {
        LGraph G;
        Vertex S;
    
        G = CreateGraph();
        scanf("%d", &S);
        printf("BFS from %d:", S);
        BFS(G, S, Visit);
    
        return 0;
    }
    
    /* 你的代码将被嵌在这里 */

    代码:

    void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
    {
        Vertex v[11];//利用一个数组队列存储遍历的节点
        PtrToAdjVNode ptg;
        int i=0;
        int j=0;
        v[j++]=S;
        Visited[S] = true;//标记为已遍历
        while(i<j)
        {
            Vertex vv = v[i++];
            Visit(vv);//输出首位
            ptg = Graph->G[vv].FirstEdge;//指向输出的队首的指针
            while(ptg)//将输出的队首的未遍历的子节点入队
            {
                if(!Visited[ptg->AdjV])
                {
                    v[j++] = ptg->AdjV;
                    Visited[ptg->AdjV] = true;
                }
                ptg = ptg->Next;
            }
        }
    }
    View Code

      7-1 畅通工程之局部最小花费问题:

    输入样例:

    4
    1 2 1 1
    1 3 4 0
    1 4 1 1
    2 3 3 0
    2 4 2 1
    3 4 5 0

    输出样例:

    3

    代码:

    #include<stdio.h>
    int main()
    {
        int dist[105],cost[105][105],visit[105]={0};
        int i,j;
        int n,m,sum=0;
        scanf("%d", &n);
        for(i=1;i<=n;i++){//每个点赋初值 
            for(j=1;j<=n;j++){
                cost[i][j]=cost[j][i]=99999;
            }
        }
        m = n*(n-1)/2;
        int a,b,chengben,zhuangtai;
        while(m--)
        {
            scanf("%d%d%d%d", &a, &b, &chengben, &zhuangtai);
            if(zhuangtai == 0)
                cost[a][b] = cost[b][a] = chengben;
            else
                cost[a][b] = cost[b][a] = 0;
        }
        for(j=1;j<=n;j++)//编号从1开始
            dist[j] = cost[1][j];
        visit[1] = 1;
        dist[1] = 0;
        for(i=1;i<n;i++)
        {
            int min=99999;
            int flag=-1;
            for(j=1;j<=n;j++)//以1号城镇为起点,找到距离1号城镇最近的城
            {
                if(visit[j]==0 && dist[j]<min)
                {
                    min = dist[j];
                    flag=j;
                }
            }
            visit[flag]=1;
            if(flag!=-1)
            {
                sum+=dist[flag];//jiang成本算入 
                for(j=1;j<=n;j++)//已经找到距离1最近的k点,再以k为起点
                {
                    if(visit[j]==0 && dist[j]>cost[flag][j])
                        dist[j] = cost[flag][j];
                }
            }
        }
        printf("%d
    ",sum);
        return 0;
    }
    View Code

      7-2 畅通工程之最低成本建设问题:

    输入样例1:

    6 15
    1 2 5
    1 3 3
    1 4 7
    1 5 4
    1 6 2
    2 3 4
    2 4 6
    2 5 2
    2 6 6
    3 4 6
    3 5 1
    3 6 1
    4 5 10
    4 6 8
    5 6 3

    输出样例1:

    12

    输入样例2:

    5 4
    1 2 1
    2 3 2
    3 1 3
    4 5 4

    输出样例2:

    Impossible

    代码:

    #include<stdio.h>
    int main()
    {
        int n,m,sum=0;
        int arr[1005][1005];
        scanf("%d%d",&n,&m);
        int dist[1001]={999999};// dist[i] 表示i节点到已有生成树的最短距离
        for(int i=1;i<=n;i++)//初始化矩阵,每个点为 ∞  
            for(int j=1;j<=m;j++)
                arr[i][j]=999999;
        int x,y,z;
        int flag=1;
        for(int i=0;i<m;i++)//生成邻接矩阵 
        {
            scanf("%d%d%d",&x,&y,&z);
            arr[x][y] = arr[y][x] = z;
        }
        for(int i=1;i<=n;i++)//记录每个点到1的最短距离
            dist[i] = arr[1][i];
        dist[1] = 0;// 访问过的点设为0
        while(1)
        {
            int a=0;
            for(int i=1;i<=n;i++)
            {
                if(dist[i]<dist[a] && dist[i])
                    a = i;
            }
            if(!a)
                break;
            sum += dist[a];
            dist[a] = 0;
            for(int i=1;i<=n;i++)
            {
                if(arr[a][i] < dist[i])
                    dist[i] = arr[a][i];
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dist[i])
                flag=0;
        }
        if(!flag)
            printf("Impossible
    ");
        else
            printf("%d
    ",sum);
        return 0;
    }
    View Code

      7-3 城市间紧急救援:

    输入样例:

    4 5 0 3
    20 30 40 10
    0 1 1
    1 3 2
    0 3 3
    0 2 2
    2 3 2

    输出样例:

    2 60
    0 1 3

    代码:

    #include <stdio.h>
    #include <string.h>
    #define INF 999999
    int n, m, s, d, vis[505], l[505][505], dis[505], p[505], sum[505], ans[505];
    void dfs(int length, int people, int dd)
    {
        int i;
        if(dd == s)
            return;
        for(i = 0 ; i < n ; i++)
        {
            if(length - l[dd][i] == dis[i] && people - p[dd] == sum[i])
            {
                dfs(dis[i], sum[i], i);
                printf("%d ", i);
                break;
            }
        }
    }
    void dij()
    {
        int i, j, k, min;
        vis[s] = 1;
        sum[s] = p[s];
        ans[s] = 1;
        for(i = 0 ; i < n ; i++)
        {
            dis[i] = l[s][i];
            if(s != i && l[s][i] != INF)
            {
                sum[i] = p[i] + p[s];
                ans[i] = 1;//
            }
        }
        for(i = 0 ; i < n-1 ; i++)
        {
            min = INF;
            for(j = 0 ; j < n ; j++)
            {
                if(!vis[j] && min > dis[j])
                {
                    min = dis[j];
                    k = j;
                }
            }
            vis[k] = 1;
            for(j = 0 ; j < n; j++)
            {
                if(!vis[j])
                {
                    if(dis[j] > dis[k] + l[k][j])
                    {
                        dis[j] = dis[k] + l[k][j];
                        sum[j] = sum[k] + p[j];
                        ans[j] = ans[k];//
                    }
                    else if(dis[j] == dis[k] + l[k][j])
                    {
                        ans[j] += ans[k];//
                        if(sum[j] < sum[k] + p[j])
                        {
                            sum[j] = sum[k] + p[j];
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        int i, j, x, y, ll;
        scanf("%d %d %d %d", &n, &m, &s, &d);
        for(i = 0 ; i < n ; i++)
            for(j = 0 ; j < n ; j++)
            {
                l[i][j] = INF;
            }
        for(i = 0 ; i < n; i++)
        {
            scanf("%d", &p[i]);
        }
        for(i = 0 ; i < m ; i++)
        {
            scanf("%d %d %d", &x, &y, &ll);
            l[x][y] = l[y][x] = ll;
        }
        if(n == 1)
        {
            printf("1 %d
    1", p[0]);
            return 0;
        }
        dij();
        printf("%d %d
    ", ans[d], sum[d]);
        printf("%d ", s);
        dfs(dis[d], sum[d], d);
        printf("%d", d);
        return 0;
    }
    View Code

      7-4 天梯地图:

    输入样例1:

    10 15
    0 1 0 1 1
    8 0 0 1 1
    4 8 1 1 1
    5 4 0 2 3
    5 9 1 1 4
    0 6 0 1 1
    7 3 1 1 2
    8 3 1 1 2
    2 5 0 2 2
    2 1 1 1 1
    1 5 0 1 3
    1 4 0 1 1
    9 7 1 1 3
    3 1 0 2 5
    6 3 1 2 1
    5 3

    输出样例1:

    Time = 6: 5 => 4 => 8 => 3
    Distance = 3: 5 => 1 => 3

    输入样例2:

    7 9
    0 4 1 1 1
    1 6 1 3 1
    2 6 1 1 1
    2 5 1 2 2
    3 0 0 1 1
    3 1 1 3 1
    3 2 1 2 1
    4 5 0 2 2
    6 5 1 2 1
    3 5

    输出样例2:

    Time = 3; Distance = 4: 3 => 2 => 5

    代码:

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int sum[521];//记录找最短时间时到原点的距离
    struct
    {
        int length;
        int time;
    }Graph[521][521];//建立地图
    struct
    {
        int visit;
        int length;
        int pre;
    }LVisit[521];//建立距离、访问表
    struct
    {
        int visit;
        int time;
        int pre;
    }TVisit[521];//建立时间、访问表
    void InitGraph(int N, int M)//创建并初始化地图
    {
        for(int i=0; i<=N; i++)//初始化各点间的距离和时间均为无穷大
        for(int j=0; j<=N; j++){
            sum[j] = 0;
            Graph[i][j].length = 9999999;
            Graph[i][j].time = 9999999;
        }
        int v1, v2, way, length, time;
        for(int i=0; i<M; i++){//读取输入创建地图
            cin>>v1>>v2>>way>>length>>time;
            Graph[v1][v2].length = length;
            Graph[v1][v2].time = time;
            if(way == 0){//非单行线,两地可互通
                Graph[v2][v1].length = length;
                Graph[v2][v1].time = time;
            }
        }
    }
    void InitVisit(int N, int S)// 初始化时间、距离、访问表
    {
        for(int i=0; i<=N; i++){
            LVisit[i].visit = 0;//初始化为未访问
            LVisit[i].length = Graph[S][i].length;//根据地图初始化到原点距离
            TVisit[i].visit = 0;//初始化为未访问
            TVisit[i].time = Graph[S][i].time;//根据地图初始化时间
            if(TVisit[i].time!=9999999){//如果和原点相通设置前驱点为原点,并设置个时间点到原点距离
                LVisit[i].pre = S;
                TVisit[i].pre = S;
                sum[i] = Graph[S][i].length;
            }
        }
        LVisit[S].visit = 1;//设置原点已访问
        TVisit[S].visit = 1;//设置原点已访问
    }
    void DST_L(int N, int S)//斯特拉求最短距离
    {
        for(int j=1; j<N; j++){
               int mlpoint = N;//设置N点为最近点,N点已设为无穷远
               for(int i=0; i<N; i++){
                   if(LVisit[i].length<LVisit[mlpoint].length&&!LVisit[i].visit)
                       mlpoint = i;
               }//求出最近点并设置为已访问
               LVisit[mlpoint].visit = 1;
               for(int i=0; i<N; i++){//更新距离
                    if(!LVisit[i].visit){
                        //更新为更短的距离
                        if(LVisit[i].length>LVisit[mlpoint].length+Graph[mlpoint][i].length){
                            LVisit[i].length = LVisit[mlpoint].length+Graph[mlpoint][i].length;
                            LVisit[i].pre = mlpoint;//设置前驱点
                        }
                        //距离相同则节点少为优
                        else if(LVisit[i].length==LVisit[mlpoint].length+Graph[mlpoint][i].length){
                                int l1=0,l2=0;
                                int pre = LVisit[i].pre;
                                while(pre!=S){
                                    l1++;
                                    pre = LVisit[pre].pre;
                                }
                                pre = mlpoint;
                                while(pre!=S){
                                    l2++;
                                    pre = LVisit[pre].pre;
                                }
                                if(l1>l2)//节点多则更新
                                LVisit[i].pre = mlpoint;
                        }
                    }
               }
        }
    
    }
    void DST_T(int N, int S)//斯特拉求最短时间
    {
        for(int j=1; j<N; j++){
            int mtpoint = N;//无穷为最短点
            for(int i=0; i<N; i++){
                if(TVisit[i].time<TVisit[mtpoint].time&&!TVisit[i].visit)
                       mtpoint = i;
            }//求出最短点并设置为已访问
            TVisit[mtpoint].visit = 1;
            for(int i=0; i<N; i++){
                if(!TVisit[i].visit){
                         //更新最短时间
                        if(TVisit[i].time>TVisit[mtpoint].time+Graph[mtpoint][i].time){
                            TVisit[i].time = TVisit[mtpoint].time+Graph[mtpoint][i].time;
                            TVisit[i].pre = mtpoint;
                            sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新最短时间的距离
                        }//时间相同则根据距离更新,距离短的优先
                        else if(TVisit[i].time==TVisit[mtpoint].time+Graph[mtpoint][i].time){
                            if(sum[i]>sum[mtpoint]+Graph[mtpoint][i].length){//选距离更短的
                                TVisit[i].pre = mtpoint;
                                sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新其距离
                            }
                        }
                    }
            }
        }
    }
    int main()
    {
        int N, M;
        cin>>N>>M;
        InitGraph(N,M);//初始化并读取输入创建图
        int S, D;
        cin>>S>>D;
        InitVisit(N, S);//创建并初始化距离、时间、访问表
        DST_L(N,S);//求最短距离
        DST_T(N,S);//求最短时间
        int lpath[521];//最短距离路径表
        int tpath[521];//最短时间路径表
        int l=520, t=520;;
        int pre = D;
        while(pre!=S){//根据目的地不断往后后移,直到后移到原点
            lpath[l]=pre;
            pre = LVisit[pre].pre;
            l--;
        }
        pre = D;
        while(pre!=S){
            tpath[t] = pre;
            pre = TVisit[pre].pre;
            t--;
        }
        if(t==l){//路径长度一样
            int flag = 0;
            for(int i=t+1; i<521; i++){//判断路径是否完全相同
                if(tpath[i]!=lpath[i])
                flag = 1;//不相等
            }
            if(flag == 1){//路径不同
                  cout<<"Time = "<<TVisit[D].time<<": "<<S;
                  for(int i = t+1; i<521; i++){
                     cout<<" => "<<tpath[i];
                  }
                  cout<<endl;
    
                  cout<<"Distance = "<<LVisit[D].length<<": "<<S;
                  for(int i = l+1; i<521; i++){
                      cout<<" => "<<lpath[i];
                  }
             }
             else{//路径相同
                cout<<"Time = "<<TVisit[D].time<<"; "<<"Distance = "<<LVisit[D].length<<": "<<S;
                for(int i = t+1; i<521; i++){
                     cout<<" => "<<tpath[i];
                }
             }
             return 0;
        }
        //路径不同
        cout<<"Time = "<<TVisit[D].time<<": "<<S;
        for(int i = t+1; i<521; i++){
            cout<<" => "<<tpath[i];
        }
        cout<<endl;
    
        cout<<"Distance = "<<LVisit[D].length<<": "<<S;
        for(int i = l+1; i<521; i++){
            cout<<" => "<<lpath[i];
        }
    
    }
    View Code

      7-5 关键活动:

    输入样例:

    7 8
    1 2 4
    1 3 3
    2 4 5
    3 4 3
    4 5 1
    4 6 6
    5 7 5
    6 7 2

    输出样例:

    17
    1->2
    2->4
    4->6
    6->7

    代码:

    #include<stdio.h>
    #include<stdlib.h>
    #define MaxSize 10000
    typedef struct Node {
        int El;
        int La;
    }Nodes;
    
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        int DEEP[101] = { 0 };    //保存点的度数
        int sort[101] = { 0 };    //保存排序结果
        int a[101][101] = { 0 };    //保存路径长度
        int end[101];
        int b[101][101];    //保存关键路径
        int sunxu[101];        //保存顺序
        Nodes *N = (Nodes *)malloc(sizeof(Nodes)*(n+1));
        for (int i = 1; i <= n; i++)
        {
            
            end[i] = -1;
            N[i].El = 0;
            N[i].La = MaxSize;
            for (int j = 1; j <= n; j++)
            {
                a[i][j] = -1;
                b[i][j] = -1;
            }
        }
        int qi, zhong, chang, count = 0, px = 0, countt = 1;
        for (int j = 1; j <= m; j++)
        {
            px = 0;
            scanf("%d %d %d", &qi, &zhong, &chang);
            a[qi][zhong] = chang;
            DEEP[zhong]++;
            for (int y = 1; y < j; y++)
            {
                if (zhong == sunxu[y]) {
                    px = 1;
                    break;
                }
            }
            if (px != 1) {
                sunxu[countt] = zhong;
                countt ++ ;
            }
        }
        int ss = 1, flag = 0,isend=1,QQ=1;
        for (int i = 1; i <= n; i++)
        {
            int z=1,isend=1;
            for (z = 1; z<=n; z++)
            {
                if (a[i][z] != -1) { isend = 0; break; }    //不是结束点
            }
            if (isend == 1) {
                end[count] = i;
                count++;
            }
            flag = -1;
            for (int j = 1; j <= n; j++)
            {
                if (DEEP[j] == 0) {
                    flag = 0;
                    DEEP[j] = -1;
                    sort[ss] = j;
                    ss++;
                    for (int k = 1; k <= n; k++)
                    {
                        if (a[j][k] != -1) {
                            DEEP[k]--;
                        }
                    }
                    break;
                }
            }
            if (flag == -1) {
                break;
            }
        }
        if (flag == 0) {
            int max = 0;
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    if (a[j][sort[i]] != -1) {
                        if (N[sort[i]].El < N[j].El + a[j][sort[i]]) {
                            N[sort[i]].El = a[j][sort[i]] + N[j].El;
                        }
                    }
                }
            }
            for (int i = 1; i <= n; i++)
            {
                if (N[i].El > max) {
                    max = N[i].El;
                }
            }
            printf("%d
    ", max); int lengths = 0;
            for (int z = 0; z < count; z++)
            {
                N[end[z]].La = max;
            }
            for (int l = n; l>=1; l--)
            {
                for (int i = 1; i <=n; i++)
                {
                    if (a[i][sort[l]]!=-1) {
                        if (N[sort[l]].La - a[i][sort[l]] < N[i].La) {
                            N[i].La = N[sort[l]].La - a[i][sort[l]];
                        }
                    }
                }
                for (int x = 1; x <=n; x++)
                {
                    if (a[x][sort[l]] != -1) {
                        if (N[sort[l]].La - a[x][sort[l]] == N[x].La&&N[x].La== N[x].El) {
                            b[x][sort[l]] = 1;
                            lengths++;
                        }
                    }
                }
            }
            for (int p = 1; p <= n; p++) {
                for (int k = countt - 1; k >= 1; k--) {
                    if (b[p][sunxu[k]] == 1) {
                        printf("%d->%d", p, sunxu[k]);
                        lengths--;
                        printf("
    ");
                    }
                }
            }
        }
        else {
            printf("0");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/3cH0-Nu1L/p/14045231.html
Copyright © 2011-2022 走看看