2012ACM成都赛区现场赛D hdu4467 Graph

在现场的时候想出了算法,可惜一直tle,结束后才想到是被重边给卡了。。。。。。

我想到的算法思路如下:

对于一个单图,一个点的相邻点中度数比它大的点的数目不会超过(2m)^(1/2)个,所以对每个点分别纪录两种颜色的比它度数小的邻点到它的边权总和,再维护所有边中颜色为00,11,01/10的边权总和。这样遇到查询操作则直接输出结果,遇到改色操作则先用此点纪录的度数比它小的邻点信息修改总值,再逐边维护度数比它大的邻点的纪录值和总值,此项的时间复杂度是O(m^1/2)。总时间复杂度是O(q*m^1/2);

由于m<=100000,q<=100000,所以此算法可过。

现场太悲剧了,完全没注意到重边的问题,当时三个人各调一题,没人帮忙,结果就卡到结束。。

#include <stdio.h>
#include "stdlib.h"

long long w[110000][2],d[110000],ed[110000][3],tot[3],col[110000],edg[110000];

int comp(const void *a,const void *b){
    
    long long t;
    t=((long long *)a)[0]-((long long *)b)[0];
    
    if (t>0){
        
        return 1;
    }
    else {
        
        if (t<0){
            
            return -1;
        }
        else {
            
            return 0;
        }
    }
}

int main(){

    long long n,m,i,j,k,t,test,q,x,y;
    char s[100];
    
    test=0;
    while (scanf("%I64d%I64d",&n,&m)!=EOF){
        
        test++;
        
        for (i=1;i<=n;i++){
            
            scanf("%I64d",col+i);
        }
        
        for (i=0;i<m;i++){
            
            scanf("%I64d%I64d%I64d",ed[i],ed[i]+1,ed[i]+2);
            
            if (ed[i][0]>ed[i][1]){
                
                t=ed[i][0];
                ed[i][0]=ed[i][1];
                ed[i][1]=t;
            }
        }
        
        qsort(ed,m,sizeof(long long )*3,comp);
        
        for (i=1,k=0;i<m;i++){
            
            if (ed[i][0]==ed[i-1][0]&&ed[i][1]==ed[i-1][1]){
                
                k++;
                ed[i-k][2]+=ed[i][2];
            }
            else {
                
                ed[i-k][0]=ed[i][0];
                ed[i-k][1]=ed[i][1];
                ed[i-k][2]=ed[i][2];
            }
        }
        
        m-=k;
        
        for (i=1;i<=n;i++){
            
            d[i]=0;
            w[i][0]=0;
            w[i][1]=0;
        }
        
        for (i=0;i<m;i++){
            
            d[ed[i][0]]++;
            d[ed[i][1]]++;
        }
        
        for (i=0;i<m;i++){
            
            if (d[ed[i][0]]>d[ed[i][1]]){
                
                t=ed[i][0];
                ed[i][0]=ed[i][1];
                ed[i][1]=t;
            }
        }
        
        qsort(ed, m, sizeof(long long )*3,comp);
        
        ed[m][0]=n+1;
        for (i=1,j=0;i<=n;i++){
            
            edg[i]=j;
            
            while (ed[j][0]==i){
                
                j++;
            }
        }
        edg[n+1]=m;
        
        tot[0]=0;
        tot[1]=0;
        tot[2]=0;
        
        for (i=0;i<m;i++){
            
            if (col[ed[i][0]]!=col[ed[i][1]]){
                
                tot[2]+=ed[i][2];
            }
            else {
                
                tot[col[ed[i][0]]]+=ed[i][2];
            }
            
            w[ed[i][1]][col[ed[i][0]]]+=ed[i][2];
        }
        
        scanf("%I64d",&q);
        
        printf("Case %I64d:\n",test);
        
        for (i=0;i<q;i++){
            
            scanf("%s",s);
            if (s[0]=='A'){
                
                scanf("%I64d%I64d",&x,&y);
                
                if (x!=y){
                    
                    printf("%I64d\n",tot[2]);
                }
                else {
                    
                    printf("%I64d\n",tot[x]);
                }
            }
            else {
                
                scanf("%I64d",&x);
                
                y=col[x];
                
                tot[y]-=w[x][y];
                tot[1-y]+=w[x][1-y];
                tot[2]+=w[x][y]-w[x][1-y];
                
                for (j=edg[x];j<edg[x+1];j++){
                    
                    w[ed[j][1]][y]-=ed[j][2];
                    w[ed[j][1]][1-y]+=ed[j][2];
                    
                    if (y==col[ed[j][1]]){
                        
                        tot[y]-=ed[j][2];
                        tot[2]+=ed[j][2];
                    }
                    else {
                        
                        tot[1-y]+=ed[j][2];
                        tot[2]-=ed[j][2];
                    }
                }
                
                col[x]=1-y;
            }
        }
    }
    return 0;
}
posted @ 2012-11-18 22:08  ustc-acm  阅读(...)  评论(... 编辑 收藏