• Reward


    Reward

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3015    Accepted Submission(s): 907


    Problem Description
    Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards.
    The workers will compare their rewards ,and some one may have demands of the distributing of rewards ,just like a's reward should more than b's.Dandelion's unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work's reward will be at least 888 , because it's a lucky number.
     
    Input
    One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000)
    then m lines ,each line contains two integers a and b ,stands for a's reward should be more than b's.
     
    Output
    For every case ,print the least money dandelion 's uncle needs to distribute .If it's impossible to fulfill all the works' demands ,print -1.
     
    Sample Input
    2 1
    1 2
    2 2
    1 2
    2 1
     
    Sample Output
    1777
    -1
     
     
    思路:拓扑排序。此题数据量大,使用邻接矩阵超出空间,需要使用链式前向星(静态建邻接表),另外还有一点要注意,要分层排序,每层的花费是一样大的。
      其实拓扑排序关键是如何更新节点的入度以及如何在计算机中存储图;
     
    下面是超空间代码:
    数据结构:邻接矩阵
     1 map[MAX][MAX];
     2 #include<stdio.h>
     3 #include<string.h>
     4 int degree[10001],map[10001][10001];
     5 
     6 int vis[10001],pre[10001];
     7 int main()
     8 {
     9     int n,m,a,b,i,j,k,t,p,flag,sum,temp;
    10     while(~scanf("%d%d",&n,&m))
    11     {
    12         memset(degree,0,sizeof(degree));
    13         memset(map,0,sizeof(map));
    14         memset(vis,0,sizeof(vis));
    15         t = sum = flag = 0;
    16         while(m--)
    17         {
    18             scanf("%d%d",&a,&b);
    19             if(!map[a][b])
    20             {
    21                 degree[b]++;
    22                 map[a][b] = 1;
    23             }
    24         }
    25         for(i = 0;i < n;i ++)
    26         {
    27             k = 0;
    28             for(j = 1;j <= n;j ++)
    29             {
    30                 if(degree[j] == 0 && vis[j] == 0)
    31                     pre[k++] = j;
    32             }
    33             sum += (888+t)*k;
    34             for(j = 0;j < k;j ++)
    35             {
    36                 vis[pre[j]] = 1;
    37                 for(p = 1;p <= n;p ++)
    38                 {
    39                     if(map[pre[j]][p] == 1 && vis[p]== 0)
    40                     {
    41                         degree[p]--;
    42                         map[pre[j]][p] = 0;
    43                     }
    44                 }
    45             }
    46             t++;
    47         }
    48         for(i = 1;i <=n;i ++)
    49         {
    50             if(degree[i])
    51             {
    52                 flag = 1;    
    53                 break ;
    54             }
    55         }
    56         if(!flag)
    57             printf("%d
    ",sum);
    58         else
    59             printf("-1
    ");
    60     }
    61     return 0;
    62 }

    下面是AC代码:

    数据结构:链式前向星
     1 int head[MAX];
     2 typedef struct 
     3 {
     4 int to;          //记录终点;
     5 int next;      //记录下一个节点的位置;
     6 int ...          //记录其他一些信息,与题有关;
     7 }EdgeNode;
     8 EdgeNode edge[MAX_m];
     9 cin >> i >> j >> ...;
    10 edge[k].to = j;
    11 edge[k].next = head[i];
    12 edge[k].... = ...;
    13 head[i] = k++;
     1   #include<stdio.h>
     2   #include<string.h>
     3   typedef struct
     4   {
     5       int to;
     6       int next;
     7   }EdgeNode;
     8   EdgeNode Edge[20005];
     9   int head[10005],node[10005];
    10  int cnt,indegree[10005],vis[10005];
    11  void init()
    12  {
    13      cnt = 0;
    14      memset(vis,0,sizeof(vis));
    15      memset(head,-1,sizeof(head));
    16          memset(indegree,0,sizeof(indegree));
    17  }
    18  
    19  void add_edge(int n,int m)
    20  {
    21      Edge[cnt].to = n;
    22      Edge[cnt].next = head[m];
    23      head[m] = cnt++;
    24  }
    25  
    26  int main()
    27  {
    28      int n,m,a,b,i,j,k,t,p,sum;
    29      while(~scanf("%d%d",&n,&m))
    30      {
    31          init();
    32          sum = p = 0;
    33          while(m--)
    34          {
    35              scanf("%d%d",&a,&b);
    36              indegree[a]++;
    37              add_edge(a,b);
    38          }
    39          for(i = 0;i < n;i ++)
    40          {
    41              t = 0;
    42              for(j = 1;j <= n;j ++)
    43              {
    44                  if(indegree[j] == 0 && vis[j] == 0)
    45                      node[t++] = j;
    46              }
    47              sum += (888+p)*t;
    48              p++;
    49              for(j = 0;j < t;j ++)
    50              {
    51                  vis[node[j]] = 1;
    52                  for(k = head[node[j]];k != -1;k = Edge[k].next)
    53                  {
    54                      if(!vis[Edge[k].to])
    55                          indegree[Edge[k].to]--;
    56                  }
    57              }
    58          }
    59          for(i = 1;i <= n;i ++)
    60          {
    61              if(indegree[i])
    62              {
    63                  sum = -1;
    64                    break ;
    65              }
    66          }
    67          printf("%d
    ",sum);
    68      }
    69      return 0;
    70  }
  • 相关阅读:
    [NOI2014]起床困难综合症(贪心+位运算)(暑假ACM1 A)
    BZOJ 2456 mode(找众数)(暑假ACM1 F)
    [POI2000]病毒(补全AC自动机)
    [NOI2005]聪聪与可可
    BZOJ4500矩阵
    网络编程物理层
    当列表推导式遇到lambda(匿名函数)
    写学生管理系统后的一些感想
    深入学习python内存管理
    python基础详解
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3374006.html
Copyright © 2020-2023  润新知