zoukankan      html  css  js  c++  java
  • 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  }
  • 相关阅读:
    第一章 简介(待续)
    第十六章 漫话网站架构师(待续)
    第十五章 网站架构师职场攻略(待续)
    第十四章 架构师领导艺术(待续)
    第十三章 大型网站典型故障分析案例(待续)
    上帝造题的七分钟2/花神游历各国/GSS4 线段树维护区间开方 By cellur925
    LuoguP1606 [USACO07FEB]荷叶塘Lilypad Pond 【最短路】By cellur925
    NOIp2013 车站分级 【拓扑排序】By cellur925
    NOI题库--盒子和小球系列 By cellur925
    关于对动态规划的思考 【转】
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3374006.html
Copyright © 2011-2022 走看看