1 条题解
-
0
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
- 上传者