zoukankan      html  css  js  c++  java
  • J

    Relief grain

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others)
    Total Submission(s): 3246    Accepted Submission(s): 955


    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=5029

    Problem Description

    The soil is cracking up because of the drought and the rabbit kingdom is facing a serious famine. The RRC(Rabbit Red Cross) organizes the distribution of relief grain in the disaster area.

    We can regard the kingdom as a tree with n nodes and each node stands for a village. The distribution of the relief grain is divided into m phases. For each phases, the RRC will choose a path of the tree and distribute some relief grain of a certain type for every village located in the path.

    There are many types of grains. The RRC wants to figure out which type of grain is distributed the most times in every village.
     

    Input

    The input consists of at most 25 test cases.

    For each test case, the first line contains two integer n and m indicating the number of villages and the number of phases.

    The following n-1 lines describe the tree. Each of the lines contains two integer x and y indicating that there is an edge between the x-th village and the y-th village.
      
    The following m lines describe the phases. Each line contains three integer x, y and z indicating that there is a distribution in the path from x-th village to y-th village with grain of type z. (1 <= n <= 100000, 0 <= m <= 100000, 1 <= x <= n, 1 <= y <= n, 1 <= z <= 100000)

    The input ends by n = 0 and m = 0.
     

    Output

    For each test case, output n integers. The i-th integer denotes the type that is distributed the most times in the i-th village. If there are multiple types which have the same times of distribution, output the minimal one. If there is no relief grain in a village, just output 0.
     

    Sample Input

    2 4 1 2 1 1 1 1 2 2 2 2 2 2 2 1 5 3 1 2 3 1 3 4 5 3 2 3 3 1 5 2 3 3 3 0 0
     

    Sample Output

    1 2 2 3 3 0 2
    Hint
    For the first test case, the relief grain in the 1st village is {1, 2}, and the relief grain in the 2nd village is {1, 2, 2}.
     

    Source

     

    题意

    给你一棵树,每次可以给一条路径分配一个值,值可以叠加,最后输出每个点被分配最多的那个值。
     

    题解

    我们先考虑一个问题,如果是在一个序列里,每次给你一个区间(l,r),问每个点最后被多少个区间覆盖。
    这道题是一道比较经典的扫描线的题,如果不会我来讲讲:
    对于每个区间(l,r),我们把他拆成两个点,(l,1) 和(r+1,-1),(1代码左端点,-1表示右端点),并将其排序。然后假想有一条扫描线从左扫到右,每次碰到一个左端点答案加一,碰到右端点答案减一。
    边扫边统计答案,答案就是到当前点,有多少个左端点还没有碰到右端点。
    这样可能有点抽象自己可以模拟几遍,应该还是能想出来的。
     
    那么和这道题有什么关系呢? 当然有关系啦,不然我为什么会将呢?
    1.我们加一颗权值线段树,对于每个区间我们增加了一维权值来确定,即(l,r,val)表示l~r赋值为val,那么还是如上一样扫描,然后答案加一的步骤改成给线段树点val加上1,
    这样每个点的答案就是线段树中最大值的位置。
     
    2.但是这是在树上,所以树链剖分将他变成一个连续序列即可。
     

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define N 200050
      5 struct Edge{int from,to,s;}edges[N<<1];
      6 struct Query
      7 {
      8   int x,val,id;
      9   bool operator <(const Query&b)const
     10   {return x<b.x;}
     11 }a[N<<2];
     12 struct Tree{int l,r,mx,wmx;}tr[N<<2];
     13 int n,m,num,ans[N];
     14 int tot,last[N];
     15 int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
     16 template<typename T>void read(T&x)
     17 {
     18   ll k=0; char c=getchar();
     19   x=0;
     20   while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
     21   if (c==EOF)exit(0);
     22   while(isdigit(c))x=x*10+c-'0',c=getchar();
     23   x=k?-x:x;
     24 }
     25 void read_char(char &c)
     26 {while(!isalpha(c=getchar())&&c!=EOF);}
     27 void AddEdge(int x,int y)
     28 {
     29   edges[++tot]=Edge{x,y,last[x]};
     30   last[x]=tot;
     31 }
     32 void dfs1(int x,int pre)
     33 {
     34   fa[x]=pre;
     35   dp[x]=dp[pre]+1;
     36   size[x]=1;
     37   son[x]=0;
     38   for(int i=last[x];i;i=edges[i].s)
     39     {
     40       Edge &e=edges[i];
     41       if (e.to==pre)continue;
     42       dfs1(e.to,x);
     43       size[x]+=size[e.to];
     44       if (size[e.to]>size[son[x]])
     45     son[x]=e.to;
     46     }
     47 }
     48 void dfs2(int x,int y)
     49 {
     50   rk[x]=++cnt;
     51   kth[cnt]=x;
     52   top[x]=y;
     53   if (son[x]==0)return;
     54   dfs2(son[x],y);
     55   for(int i=last[x];i;i=edges[i].s)
     56     {
     57       Edge e=edges[i];
     58       if (e.to==fa[x]||e.to==son[x])continue;
     59       dfs2(e.to,e.to);
     60     }
     61 }
     62 void push_up(Tree &c,Tree a,Tree b)
     63 {
     64   c.mx=max(a.mx,b.mx);
     65   c.wmx=c.mx==a.mx?a.wmx:b.wmx;
     66 }
     67 void bt(int x,int l,int r)
     68 {
     69   tr[x]=Tree{l,r,0,0};
     70   if (l==r){tr[x].wmx=l;return;}
     71   int mid=(l+r)>>1;
     72   bt(x<<1,l,mid);
     73   bt(x<<1|1,mid+1,r);
     74 }
     75 void update(int x,int p,int tt)
     76 {
     77   if (p<=tr[x].l&&tr[x].r<=p)
     78     {
     79       tr[x].mx+=tt;
     80       tr[x].wmx=tr[x].l;
     81       return;
     82     }
     83   int mid=(tr[x].l+tr[x].r)>>1;
     84   if (p<=mid)update(x<<1,p,tt);
     85   if (mid<p)update(x<<1|1,p,tt);
     86   push_up(tr[x],tr[x<<1],tr[x<<1|1]);
     87 }
     88 void change(int x,int y,int tt)
     89 {
     90   int fx=top[x],fy=top[y];
     91   while(fx!=fy)
     92     {
     93       if (dp[fx]<dp[fy])swap(x,y),swap(fx,fy);
     94       a[++num]=Query{rk[fx],tt,1};
     95       a[++num]=Query{rk[x]+1,tt,-1};
     96       x=fa[fx];fx=top[x];
     97     }
     98   if (dp[x]<dp[y])swap(x,y);
     99   a[++num]=Query{rk[y],tt,1};
    100   a[++num]=Query{rk[x]+1,tt,-1};
    101 }
    102 void work()
    103 {
    104   read(n); read(m);
    105   if (n==0)exit(0);
    106   for(int i=1;i<=n-1;i++)
    107     {
    108       int x,y;
    109       read(x); read(y);
    110       AddEdge(x,y);
    111       AddEdge(y,x);
    112     }
    113   dfs1(1,0);
    114   dfs2(1,1);
    115   bt(1,0,100005);
    116   for(int i=1;i<=m;i++)
    117     {
    118       int x,y,tt;
    119       read(x); read(y); read(tt);
    120       change(x,y,tt);
    121     }
    122   sort(a+1,a+num+1);
    123   for(int i=1;i<=num-1;i++)
    124     {
    125       int l=a[i].x;
    126       update(1,a[i].val,a[i].id);
    127       while(a[i+1].x==a[i].x)
    128     //update(1,a[++i].val,a[i].id);
    129     i++,update(1,a[i].val,a[i].id);
    130       
    131       for(int j=l;j<a[i+1].x;j++)
    132     ans[kth[j]]=tr[1].wmx;
    133     }
    134   for(int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    135 }
    136 void clear()
    137 {
    138   tot=0; cnt=0; num=0;
    139   memset(last,0,sizeof(last));
    140   memset(ans,0,sizeof(ans));
    141 }
    142 int main()
    143 {
    144 #ifndef ONLINE_JUDGE
    145   freopen("aa.in","r",stdin);
    146 #endif
    147   while(1)
    148     {
    149       clear();
    150       work();
    151     }
    152 }
    View Code
     
     
  • 相关阅读:
    synchronized对比cas
    java 数据集合类
    【转载】S2SH
    【转载】Solr4+IKAnalyzer的安装配置
    【转】基于CXF Java 搭建Web Service (Restful Web Service与基于SOAP的Web Service混合方案)
    【转载】solr初体验
    【转载】CSS 盒子模型
    【转载】div层调整zindex属性无效原因分析及解决方法
    【转载】 IE/Firefox每次刷新时自动检查网页更新,无需手动清空缓存的设置方法
    mysql ODBC connector相关问题
  • 原文地址:https://www.cnblogs.com/mmmqqdd/p/10793675.html
Copyright © 2011-2022 走看看