zoukankan      html  css  js  c++  java
  • How Long Does It Take

    好长时间没写博客了,真心惭愧啊!

    废话少说,原题链接:https://pta.patest.cn/pta/test/1342/exam/4/question/24939

    题目如下:

    Given the relations of all the activities of a project, you are supposed to find the earliest completion time of the project.

    Input Specification:

    Each input file contains one test case. Each case starts with a line containing two positive integers NNN (≤100le 100100), the number of activity check points (hence it is assumed that the check points are numbered from 0 to N−1N-1N1), and MMM, the number of activities. Then MMM lines follow, each gives the description of an activity. For the i-th activity, three non-negative numbers are given: S[i], E[i], and L[i], where S[i] is the index of the starting check point, E[i] of the ending check point, and L[i] the lasting time of the activity. The numbers in a line are separated by a space.

    Output Specification:

    For each test case, if the scheduling is possible, print in a line its earliest completion time; or simply output "Impossible".

    Sample Input 1:

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

    Sample Output 1:

    18
    

    Sample Input 2:

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

    Sample Output 2:

    Impossible

    这道题不难,本质上就是一道拓扑排序的问题,只不过增加了权重,成为了一道关键路径的问题,此类拓扑排序问题的核心思想就是先在图中找到入度为0的点,对其进行操作,然后将于该点相邻的边删除,继续对剩下的图重复这一过程。为了提高算法的效率,陈越老师讲过可以在每次删除边时,检查其它顶点是否入度为0,如果为0就将其放在一个容器里面(我用的是队列),下次用的时候就可以直接从容器里面取出。拓扑排序一般是较为稀疏的图,应该用邻接表存储图合适,但我为了写起来简单,就用了邻接矩阵。以下是我的代码:

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<stdbool.h>
      4 #define Max 105
      5 #define INFINITY 65535
      6 typedef struct QNode{
      7     int front,rear;
      8     int Data[Max];
      9     int Maxsize;
     10 }Quenue;
     11 
     12 Quenue *CreateQ(int N)
     13 {
     14     Quenue *Q=(Quenue *)malloc(sizeof(struct QNode));
     15     Q->front=Q->rear=0;
     16     Q->Maxsize=N+1;
     17     return Q;
     18 }
     19 
     20 bool IsFull(Quenue *Q)
     21 {
     22     return ((Q->front+1)%Q->Maxsize == Q->rear);
     23 }
     24 
     25 void Push(Quenue *Q,int v)
     26 {
     27     if (!IsFull(Q))
     28     {
     29         Q->front=(Q->front+1)%Q->Maxsize;
     30         Q->Data[Q->front]=v;
     31     }
     32 }
     33 
     34 bool IsEmpty(Quenue *Q)
     35 {
     36     return (Q->front==Q->rear);
     37 }
     38 
     39 int Pop(Quenue *Q)
     40 {
     41     if (!IsEmpty(Q))
     42     {
     43         Q->rear=(Q->rear+1)%Q->Maxsize;
     44         return (Q->Data[Q->rear]);
     45     }
     46 }
     47 
     48 int G[Max][Max];
     49 int N,M;
     50  51 
     52 void TopSort()
     53 {
     54     int Indegree[Max]={0};
     55     int v,w,weight,cnt=0;
     56     int endcnt=0; //有多个终点是,用来记录是否为终点的变量
     57     int dist[Max]={0};
     58     Quenue *Q=CreateQ(N);
     59    /* 初始化各顶点的入度值 */
     60     for (v=0;v<N;v++)
     61     {
     62         for (w=0;w<N;w++)
     63         {
     64             if ( G[w][v]<INFINITY)Indegree[v]++;
     65         }
     66     }
     67     /*入度为0的顶点入队 */
     68     for (v=0;v<N;v++)
     69     {
     70         if (Indegree[v]==0){Push(Q,v);}
     71     }
     72     /*拓扑排序*/
     73     weight=0;
     74     while (!IsEmpty(Q))
     75     {
     76         v=Pop(Q);
     77         cnt++;
     78         for (w=0;w<N;w++)
     79         {
     80             if (G[v][w]<INFINITY)
     81             {
     82                 if (dist[v]+G[v][w]>dist[w])dist[w]=dist[v]+G[v][w];
     83                 if (--Indegree[w]==0)Push(Q,w);
     84                 endcnt++;
     85             }
     86         }
     87         if (endcnt==0)  //此时v为终点
     88         {
     89             if (dist[v]>weight)weight=dist[v];
     90         }
     91         endcnt=0;
     92     }
     93     if (cnt!=N)printf("Impossible");
     94     else printf("%d",weight);
     95     return ;
     96 }
     97 
     98 int main()
     99 {
    100     scanf("%d %d",&N, &M);
    101     int i,j,v,w,weight;
    102     for (i=0;i<N;i++){
    103     for (j=0;j<N;j++){G[i][j]=INFINITY;}}
    104     for (i=0;i<M;i++)
    105     {
    106         scanf("%d %d %d",&v, &w, &weight);
    107         G[v][w]=weight;
    108     }
    109     TopSort();
    110     return 0;
    111 }
  • 相关阅读:
    Thinking in Java Reading Note(9.接口)
    Thinking in java Reading Note(8.多态)
    Thinking in Java Reading Note(7.复用类)
    SQL必知必会
    Thinking in Java Reading Note(5.初始化与清理)
    Thinking in Java Reading Note(2.一切都是对象)
    鸟哥的Linux私房菜笔记(1.基础)
    Thinking in Java Reading Note(1.对象导论)
    CoreJava2 Reading Note(2:I/O)
    CoreJava2 Reading Note(1:Stream)
  • 原文地址:https://www.cnblogs.com/wuxiaotianC/p/6082945.html
Copyright © 2011-2022 走看看