1. 程式人生 > >How Many Answers Are Wrong HDU

How Many Answers Are Wrong HDU

題意

第一行兩個整數n, m; n表示陣列長度,一共m組 。之後每行三個整數,a, b, v:表示陣列第a個元素到b第個元素的和為v

判斷輸入的區間有幾組是錯誤的。

思路

看程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200005;
int pre[maxn];
int sum[maxn];      //表示該點到根節點的距離
int find(int x)
{
    //這個程式碼的高明之處就在於Find過程中就將所需要的結點進行更新,並且每棵樹的高度不會超過2,所以遞迴深度也很淺

   if(x!=pre[x])
   {
       int t=pre[x];
       //將尋找根途中碰到的所有的結點都直接接到根上,這樣可以降低遞迴深度,
       pre[x]=find(pre[x]);
       sum[x]+=sum[t];    //利用遞迴函式的特性,更新sum陣列
   }
   return pre[x];
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int cnt=0;
        for(int i=0;i<=n;i++)            //初始化
        {
            pre[i]=i;
            sum[i]=0;
        }
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            a--;              //兩個閉區間不好處理,轉化為左開右閉。半閉半開區間有一個性質,就是 (a,b]+(b,c]=(a,c]。
            int x=find(a);  //a的樹根
            int y=find(b);  //b的樹根
            if(x==y)
            {
                if((sum[a]-sum[b])!=c)
                    cnt++;
            }
            else
            {
                pre[x]=y;   //將a樹移到b樹上
                //a到x的距離為sum[a],b到y的距離為sum[b],a到b的距離為c

                sum[x]=sum[b]+c-sum[a];  //公式看下邊連線
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

本文參考部落格