1 条题解

  • 0
    @ 2025-9-10 9:13:07

    C++ :

    /*所求答案是 西格玛(price[i]*西格玛(i的子孙的weight)),可以变换为 西格玛(weight[i]*dist[i]).price 是边的单价,dist是点到根的最短路。weight是点的重量。
    因为对于每个点,他前面的边在算价钱的时候都要算到他,所以求最短路 使答案最小。
    一个点无法到达时,输出no answer。
    数据超大,dijkstra+heap 2.7秒
    */
    #include<stdio.h>
    #include<string.h>
    
    const int N = 50008;
    const long long INF = 1111111;
    
    struct HEAP
    {
        long long data;
        int num;
    };
    
    struct NODE
    {
        long long data;
        int num;
        int next;
    };
    
    struct DIJ
    {
        long long data;
        int next,last; //qian,hou;
        int vis;
    };
    
    HEAP heap[N*2];
    NODE list[N*2];
    DIJ dis[N*2];
    long long w[N*2];
    int hash[N*2];
    int e,v;
    int hsize,next;
    
    void csh()
    {
        int i;
        memset(w,0,sizeof(w));
        memset(hash,0,sizeof(hash));
        next = hsize = 0;
        for(i=0;i<v;i++)
        {
            dis[i].data = INF;
            dis[i].next = -1;
            dis[i].vis = 0;
        }
    }
    
    void insert(int x,int y,long long p)
    {
        list[next].data = p;
        list[next].next = -1;
        list[next].num = y;
        next++;
        if(dis[x].next == -1)
            dis[x].next = next - 1;
        else
            list[dis[x].last].next = next - 1;
        dis[x].last = next - 1;
    }
    
    void swap(int x,int y)
    {
        struct temp
        { long long data; int num; }tmp;
    
        tmp.data = heap[x].data;
        tmp.num = heap[x].num;
        heap[x].data = heap[y].data;
        heap[x].num = heap[y].num;
        heap[y].data = tmp.data;
        heap[y].num = tmp.num;
    }
    
    void sift_up(int k)
    {
        while(k > 0 && heap[(k-1)/2].data > heap[k].data)
        {
            hash[heap[k].num] = (k-1) / 2;
            hash[heap[(k-1)/2].num] = k;
            swap(k,(k-1)/2);
            k = (k-1) / 2;
        }
    }
    
    void sift_down(int k)
    {
        int flag = 0;
        while(k < hsize && !flag)
        {
            int l = k*2 + 1;
            int r = k*2 + 2;
            int t = -1;
            flag = 1;
            if(r < hsize)
            {    if(heap[l].data <= heap[r].data)
                    t = l;
                else
                    t = r;
            }
            else if(l < hsize)
                t = l;
            if(t != -1 && (heap[t].data < heap[k].data))
            {
                hash[heap[k].num] = t;
                hash[heap[t].num] = k;
                swap(k,t);
                k = t;
                flag = 0;
            }
        }
    }
    
    void dijkstra_heap(int s,int en)
    {
        int i,mark,tmp,k,j;
        long long min,d;
        dis[s].data = 0;
        for(i=0;i<en;i++)
        {
            heap[hsize].data = dis[i].data;
            heap[hsize].num = i;
            hsize++;
            hash[i] = hsize-1;
            sift_up(hsize-1);
        }
        
        for(i=0;i<en-1;i++)
        {
            min = heap[0].data;
            mark = heap[0].num;
            if(min == INF) return ;
            dis[mark].vis = 1;
            tmp = heap[hsize-1].num;
            hash[tmp] = 0;
            hash[mark] = hsize - 1;
            swap(0,hsize - 1);
            hsize--;
            sift_up(hash[tmp]);
            sift_down(hash[tmp]);
            for(j=dis[mark].next;j!=-1;j=list[j].next)
            {
                k = list[j].num;
                d = dis[mark].data + list[j].data;
                if(d < dis[k].data)
                {
                    dis[k].data = d;
                    heap[hash[k]].data = d;
                    sift_up(hash[k]);
                }
            }
        }
    }
    
    int main()
    {
    
    	//freopen("Christmas.in", "r", stdin);
    	//freopen("Christmas.out", "w", stdout);
        int i,j,x,y,t,flag;
        long long sum,p;
    
     //   scanf("%d",&t);
      //  while(t--)
      //  {
            scanf("%d%d",&v,&e);
            csh();
            for(i=0;i<v;i++)
                scanf("%lld",&w[i]);
            for(i=0;i<e;i++)
            {
                scanf("%d%d%lld",&x,&y,&p);
                x--;y--;
                if(x != y)
                {
                    insert(x,y,p);
                    insert(y,x,p);
                }
            }
            dijkstra_heap(0,v);
            flag = sum = 0;
            for(i=0;i<v;i++)
            {    
                if(dis[i].data == INF)
                {    flag = 1; break;    }
                sum += w[i] * dis[i].data;
            }
            if(flag)
                printf("No Answer\n");
            else
                printf("%lld\n",sum);
     //   }
        return 0;
    }
    
    

    Pascal :

    var n,m,i,j,l,r,tt,ii:longint;
        ans:int64;
        x:array[0..100000,1..3]of longword;
        f:array[0..2000000]of int64;
        s,a,b:array[0..200000]of longint;
        p:boolean;
        procedure sort(l,r: longint);
          var
             i,j,xx: longint;
          begin
             i:=l;
             j:=r;
             xx:=x[(l+r) div 2,1];
             repeat
               while x[i,1]<xx do
                inc(i);
               while xx<x[j,1] do
                dec(j);
               if not(i>j) then
                 begin
                    x[0]:=x[i];
                    x[i]:=x[j];
                    x[j]:=x[0];
                    inc(i);
                    j:=j-1;
                 end;
             until i>j;
             if l<j then
               sort(l,j);
             if i<r then
               sort(i,r);
          end;
        procedure ff;
    var i,v,xx,j:longint;
    begin
    v:=0;
    for i:=l to r do begin
    xx:=b[i];
    for j:=s[xx] to s[xx+1]-1 do
    if f[xx]+x[j,3]<f[x[j,2]]then begin
    f[x[j,2]]:=f[xx]+x[j,3];
    inc(v);
    b[r+v]:=x[j,2];
    end;
    end;
    l:=r+1;r:=r+v;
    if l<=r then ff;
    end;
    begin
    //assign(input,'christmas.in');reset(input);
    //assign(output,'christmas.out');rewrite(output);
    //readln(tt);
    //for ii:=1 to tt do begin
    p:=true;
    readln(n,m);
    if n<2 then begin writeln(0);close(input);close(output);exit;end;
    for i:=1 to n do read(a[i]);
    for i:=1 to m do begin
    readln(x[i,1],x[i,2],x[i,3]);
    x[m+i,1]:=x[i,2];x[m+i,2]:=x[i,1];x[m+i,3]:=x[i,3];
    end;
    sort(1,m*2);
    f[1]:=0;
    for i:=2 to 200000 do f[i]:=9999999999;
    x[0,1]:=0;
    for i:=1 to m*2 do if x[i,1]<>x[i-1,1] then s[x[i,1]]:=i;
    s[n+1]:=m*2+1;
    for i:=1 to n do if s[i]=0 then begin writeln('No Answer');close(input);close(output);(*p:=false;break;*)exit;end;
    //if not p then continue;
    l:=1;r:=1;b[1]:=1;
    ff;
    ans:=0;
    for i:=2 to n do if f[i]<9999999999 then ans:=ans+f[i]*a[i] else begin writeln('No Answer');close(input);close(output);(*p:=false;break;*)exit;end;
    //if not p then continue;
    writeln(ans);
    //end;
    //close(input);close(output);
    end.
    
    
    • 1

    信息

    ID
    4215
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者