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 }
  • 相关阅读:
    (转)C#中String跟string的“区别”
    C#中的this关键字
    (转)VS2015基础 指定一个或多个项目执行
    C# 中如何输出双引号(转义字符的使用)
    (转) C#中使用throw和throw ex抛出异常的区别
    springboot
    Zookeeper
    Maven
    springboot
    springboot
  • 原文地址:https://www.cnblogs.com/wuxiaotianC/p/6082945.html
Copyright © 2011-2022 走看看