zoukankan      html  css  js  c++  java
  • ICPC archive 6187 并查集

    https://icpcarchive.ecs.baylor.edu

    因为给你的是两物品的重量差,问你的也是两物品的重量差,所以,如果告诉你两物品的重量差,这就相当于给你一种等价关系,把两物品所在的集合合并,并能推导出合并完的集合内所有的物品的差,为了加速该过程,可以在每个子结点记录自己与父结点的重量差,然后在查找时路径压缩,让结点的父结点直接是根结点,重量差就要更新,这步要做对,自己推导推导怎么做,然后在合并两集合时采用启发式合并,说白了就是把结点数少的那个集合作为结点数多的集合的子结点。这样操作会少一些。

    贴代码:

    View Code
      1 #include <cstdio>
      2 #define MAXN 100005
      3 int n;
      4 struct point
      5 {
      6     int pre,w;
      7 } p[MAXN];
      8 int cnt[MAXN];
      9 int find(int x)
     10 {
     11     int s = x;
     12     int cur = 0;
     13     while(p[s].pre > 0)
     14     {
     15         cnt[cur++] = p[s].w;
     16         s = p[s].pre;
     17     }
     18     for(int i = cur-1;i > 0; i--)
     19     cnt[i-1] = cnt[i]+cnt[i-1];
     20     cur= 0 ;
     21     while(s != x)
     22     {
     23         point  tmp = p[x];
     24         p[x].pre = s;
     25         p[x].w = cnt[cur++];
     26         x = tmp.pre;
     27     }
     28     return s;
     29 }
     30 void UFset(int x,int y,int w)
     31 {
     32     int s;
     33     int r1 = find(x);
     34     int r2 = find(y);
     35     if(r1 == r2) return ;
     36     int total = p[r1].pre + p[r2].pre;
     37     if(p[r1].pre > p[r2].pre)
     38     {
     39         int t1 = w;
     40         s = y;
     41         while(p[s].pre > 0)
     42         {
     43             t1 += p[s].w;
     44             s = p[s].pre;
     45         }
     46         s = x;
     47         int t2 = 0;
     48         while(p[s].pre > 0)
     49         {
     50             t2 += p[s].w;
     51             s = p[s].pre;
     52         }
     53         p[r1].pre = r2;
     54         p[r1].w = t1-t2;
     55         p[r2].pre = total;
     56     }
     57     else
     58     {
     59         int t1 = -w;
     60         s = x;
     61         while(p[s].pre > 0)
     62         {
     63             t1 += p[s].w;
     64             s = p[s].pre;
     65         }
     66         s = y;
     67         int t2 = 0;
     68         while(p[s].pre > 0)
     69         {
     70             t2 += p[s].w;
     71             s = p[s].pre;
     72         }
     73         p[r2].pre = r1;
     74         p[r2].w = t1-t2;
     75         p[r1].pre = total;
     76     }
     77 }
     78 void computer(int x,int y)
     79 {
     80     int t1 = find(x);
     81     int t2 = find(y);
     82     if(t1 != t2)
     83     {
     84         printf("UNKNOWN\n");
     85         return ;
     86     }
     87     printf("%d\n",p[x].w-p[y].w);
     88 }
     89 int main()
     90 {
     91 //    freopen("in1.cpp","r",stdin);
     92     int m;
     93     int x,y,w;
     94     char a[3];
     95     while(~scanf("%d%d",&n,&m))
     96     {
     97         if(n == 0 && m == 0)  break;
     98         for(int i=1; i<=n; i++)
     99         {
    100             p[i].pre = -1;
    101             p[i].w = 0;
    102         }
    103         while(m--)
    104         {
    105             scanf("%s",a);
    106             if(a[0] == '!')
    107             {
    108                 scanf("%d%d%d",&x,&y,&w);
    109                 UFset(x,y,w);
    110             }
    111             else
    112             {
    113                 scanf("%d%d",&x,&y);
    114                 computer(x,y);
    115             }
    116         }
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    Solr查询参数sort(排序)
    使用SolrNet访问Solr-5.5.0
    java impl
    Solr Facet 搜索时,facet.missing = true 的真正含义
    为solr增加用户验证
    每日晨读_20140705
    说说常用的服务器操作
    如何添加自定义脚本到开机自启动
    记录一个mysql连接慢的问题
    javascript时间戳和日期字符串相互转换
  • 原文地址:https://www.cnblogs.com/allh123/p/2999738.html
Copyright © 2011-2022 走看看