Description
Input
Output
Sample Input
10 5 1 10 100 7 10 28 1 3 32 4 6 41 6 6 1
Sample Output
1
java代码:真不知道,而且没有解决方案,就是超内存。
import java.util.Scanner; import java.math.BigInteger; import java.math.BigDecimal; import java.util.Arrays; import java.util.ArrayList; public class Main { final static int maxn = 200000 + 5; static int [] par = new int [maxn]; static int [] val = new int [maxn]; static int N,M,a,b,c,ans; public static void init() { Arrays.fill(par,-1); Arrays.fill(val,0); } public static int find(int x) { /******************************************/ /*this result is get max(类似于后辍和,将他的范围扩大,以至于减少比较的次数)*/ /******************************************/ if(par[x] < 0)return x; int t = par[x]; par[x] = find(par[x]); val[x] += val[t]; return par[x]; } public static void unite(int u,int v,int z) { int x = find(u); int y = find(v); par[y] = x; val[y] = val[u] - val[v] - z; } public static void main(String [] agrs) { Scanner cin=new Scanner(System.in); while(cin.hasNext()) { ans=0; init(); N=cin.nextInt(); M=cin.nextInt(); while(M-->0) { a=cin.nextInt(); b=cin.nextInt(); c=cin.nextInt(); int x=find(a); int y=find(b+1); if(x==y) { if(val[a]-val[b+1]!=c) { ans++; } } else { unite(a,b+1,c); } } System.out.println(ans); } } }
C++代码
对于这道题目,主要是对情况的思考问题,将对一个区间处理,我最先是想用线段树做的,但是感觉极有可能超时,所以放弃了,然后发现这个像我们平时做的前辍和以及后辍和,于是就开始分析情况,对于其中的一个特别重要的部分,便是unite()函数里面的处理,当然,有些人可能觉得Find()函数里面的东西也有些深奥,那是你没有仔细思考,只是简单的用一个递归将后面的后辍和计算出来而已。
现在主要讲unite()部分的内容,为什么是这样了其实就是一个简单的合并过程:
[[[[[]]]]]]]][[[[]]]]],这个代表着一个个小区间,在你之前的操作,一定会是num[u]>num[v]+z;至于为什么,就是Find起的作用,他讲你之前的一些操作的区间全部链接到了一起,所以后面增加的一定是比他小的,或者是从来没有在已知区间出现过的区间。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=200000+; int par[maxn],num[maxn];//num[i] indicate [i,par[i]) is minus. void init() { memset(par,-1,sizeof(par)); memset(num,0,sizeof(num)); } int find(int x) { if(par[x]<0)return x; int n=par[x]; par[x]=find(par[x]); num[x]+=num[n]; return par[x]; } void uinte(int u,int v,int z) { int x=find(u); int y=find(v); par[y]=x; num[y]=num[u]-num[v]-z; return; } int main() { int N,M; int a,b,s,ans,c; while(~scanf("%d%d",&N,&M)) { init(); ans=0; for(int i=0; i<M; i++) { scanf("%d %d %d",&a,&b,&c); int x=find(a); int y=find(b+1); if(x==y) //If par[a]==par[b+1] .........[a,b]<->[b+1,par[b+1]] { if(num[a]-num[b+1]!=c) //If the event conflict,two number are not equal,so add a record. { ans++; } } else //Add data into the array. { uinte(a,b+1,c); } } printf("%d\n",ans); } return 0; }