zoukankan      html  css  js  c++  java
  • HDU 2647 Reward

    大体思路就是简单的拓扑排序。

    写的时候没有看模板,都是自己一点一点改的,应该没有模板效率高。

    还用了一点优先队列的思想,用了并查集的方法检查是否存在环。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 
      5 using namespace std;
      6 
      7 struct N
      8 {
      9     int data;
     10     int n,money;
     11     N *next;
     12 }*head[10010];
     13 
     14 void init(int n)//初始化函数
     15 {
     16     for(int i = 1;i <= n; i++)
     17     {
     18         head[i] = (struct N *)malloc(sizeof(struct N));
     19         head[i]->n = 0;
     20         head[i]->data = -1;
     21         head[i]->next = NULL;
     22         head[i]->money = -1;
     23     }
     24 }
     25 
     26 int h[10010];//为并查集准备的数组
     27 
     28 int seek(int u,int v)//并查集
     29 {
     30     while(h[v] != v)
     31     {
     32         v = h[v];
     33     }
     34     if(u != v) {h[u] = v;return 1;}
     35     else return 0;
     36 }
     37 
     38 void link(int u,int v)
     39 {
     40     N *p1 = head[u],*p2 = head[u]->next;
     41     for(;p2 != NULL; p1 = p1->next,p2 = p2->next)
     42     {
     43         if(p2->data == v) return;
     44         if(p1->data < v && v < p2->data)
     45         {
     46             N *p = (struct N *)malloc(sizeof(struct N));
     47             p->data = v;
     48             head[v]->n++;
     49             p->next = p1->next;
     50             p1->next = p;
     51             return;
     52         }
     53     }
     54     N *p = (struct N *)malloc(sizeof(struct N));
     55     p->data = v;
     56     head[v]->n++;
     57     p->next = NULL;
     58     p1->next = p;
     59     return;
     60 }
     61 
     62 int sum;
     63 
     64 void check(int u,int min)
     65 {
     66     int q[10001],s = 0,e = 0;
     67     for(N *p = head[u]->next; p != NULL; p = p->next)
     68     {
     69         if(head[p->data]->money == -1)//如果此点第一次被访问,直接将min加入sum
     70         {
     71             sum += min;
     72             head[p->data]->money = min;
     73         }
     74         else if(head[p->data]->money < min)//如果此点已经被访问,则需比较当前的min是否大于其当前的奖励。
     75         {
     76             sum = sum + (min - head[p->data]->money);
     77             head[p->data]->money = min;
     78         }
     79         q[e++] = p->data;
     80     }
     81     for(s = 0,min = min+1;s < e; s++)
     82     {
     83         check(q[s],min);
     84     }
     85 }
     86 
     87 int main()
     88 {
     89 
     90     int m,n,u,v,i,flag;
     91     while(scanf("%d %d",&n,&m) != EOF)
     92     {
     93         for(i = 1;i <= n; i++)
     94             h[i] = i;
     95         init(n);
     96         flag = 1;
     97         while(m--)
     98         {
     99             scanf("%d %d",&v,&u);
    100             if(flag && seek(u,v))//seek——并查集  用来检查是否存在环
    101             {
    102                 link(u,v);
    103             }
    104             else flag = 0;
    105         }
    106         if(flag)
    107         {
    108             sum = 888*n;
    109             for(i = 1;i <= n; i++)
    110             {
    111                 if(head[i]->n == 0)
    112                     check(i,1);
    113             }
    114             printf("%d\n",sum);
    115         }
    116         else printf("-1\n");
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    Linux文件目录结构一览表
    Linux一切皆文件(包含好处和弊端)
    Linux使用注意事项(新手必看)
    为什么建议使用虚拟机来安装Linux?
    开发中出现的问题
    为什么很多公司都在招测试开发?
    Linux cat查看文件,查找关键字(grep),统计(wc -l)
    性能测试
    Linux的感性理解
    使用Python循环插入10万数据
  • 原文地址:https://www.cnblogs.com/zmx354/p/3031431.html
Copyright © 2011-2022 走看看