博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 3013 Big Christmas Tree
阅读量:5102 次
发布时间:2019-06-13

本文共 4117 字,大约阅读时间需要 13 分钟。

ContractedBlock.gif
ExpandedBlockStart.gif
View Code
#include
#include
using namespace std; #define maxn 50002 const __int64 inf=(__int64)1<<63-1; struct Edge {
int v; int weight; int next; }Vertex[4*maxn]; int head[maxn],curr; int cases,v,e,i,j,edge[maxn][3],w[maxn]; void add_edge(int s,int t,int w) //新增结点不用申请空间, 跑了 579 MS {
Vertex[curr].v=t; Vertex[curr].weight=w; Vertex[curr].next=head[s]; head[s]=curr++; } bool S[maxn]; __int64 distD[maxn],sum; void spfa(int u) {
fill(distD,distD+v+1,inf); distD[u]=0; memset(S,0,sizeof(S[0])*(v+1)); S[u]=1; deque
col; col.push_back(u); while(!col.empty()) {
int uu=col.front(); col.pop_front(); S[uu]=0; for(i=head[uu];i!=-1;i=Vertex[i].next) {
if(distD[uu]+Vertex[i].weight

  

ContractedBlock.gif
ExpandedBlockStart.gif
View Code
#include
//单源最短路SPFA #include
using namespace std; #define maxn 50002 const __int64 inf=(__int64)1<<63-1; //inf=4611686018427387904 //(1)#define inf (1<<63)-1 (2)const __int64 inf=(__int64)(1<<63)-1; (3)const __int64 inf=(1<<63)-1; 这三者的值都为-1 struct Edge {
int index; int weight; Edge *next; }Vertex[maxn]; int cases,v,e,i,j,edge[maxn][3],w[maxn]; void add_edge(int s,int t,int w) {
Edge *q=new Edge; //每次都new 耗时间,跑了2391 MS q->index=t;q->weight=w; q->next=Vertex[s].next;Vertex[s].next=q; //不必检查重边,直接插入即可 } bool S[maxn]; __int64 distD[maxn],sum; //这里要声明为__int64 void spfa(int u) {
fill(distD,distD+v+1,inf); distD[u]=0; memset(S,0,sizeof(S[0])*(v+1)); S[u]=1; int uu,vv,wei; deque
col; //spfa 队列 col.push_back(u); while(!col.empty()) {
uu=col.front(); col.pop_front(); S[uu]=0; Edge *curr=Vertex[uu].next; while(curr!=NULL) {
vv=curr->index;wei=curr->weight; if(distD[uu]+wei
next; } } for(i=1;i<=v;++i) if(distD[i]==inf) {
printf("No Answer\n"); return ; } sum=0; for(i=1;i<=v;++i) sum+=w[i]*distD[i]; printf("%I64d\n",sum); } int main() {
scanf("%d",&cases); while(cases--) {
scanf("%d%d",&v,&e); for(i=1;i<=v;++i) scanf("%d",&w[i]); for(i=1;i<=v;++i) Vertex[i].next=NULL; for(i=1;i<=e;++i) {
scanf("%d%d%d",&edge[i][0],&edge[i][1],&edge[i][2]); add_edge(edge[i][0],edge[i][1],edge[i][2]); //双向边 add_edge(edge[i][1],edge[i][0],edge[i][2]); } spfa(1); } return 0; } /* 要注意以下情况: (1)当v=0,1时都是输出0,但不必另外加判断, 因为当v=0时,在决定是否No Answer的for循环for(i=1;i<=v;++i)本身就不会执行,sum=0 当v=1时,生成树中的根结点1的distD[1]=0,其他结点(若有的话)的distD也为0,sum+=w[i]*distD[i];sum仍然为0 (2)也不必另外筛除掉指向自己的边,因为在SPFA函数内的if(distD[v]+w
index=t;q->weight=w; Edge *tmp=Vertex[s].next; while(tmp!=NULL&&tmp->index!=t) tmp=tmp->next; if(tmp==NULL) {
q->next=Vertex[s].next;Vertex[s].next=q; //没找到重边 } else tmp->weight=min(tmp->weight,w); //找到重边,取较小值 } 当然,如果是邻接矩阵就要判断重边了,取其中的最小值 (4)边是无向边 (5)要注意inf的取值,最短路径数组distD和结果sum 都要用__int64 存储 另外,不用deque,也可用循环队列,如下: void spfa(int u) {
fill(distD,distD+v+1,inf); distD[u]=0; memset(S,0,sizeof(S[0])*(v+1)); S[u]=1; int uu,vv,wei; int deq[maxn],head=0,rear=1; deq[0]=u; while(head!=rear) //循环队列 {
uu=deq[head++]; if(head==maxn) head=0; S[uu]=0; Edge *curr=Vertex[uu].next; while(curr!=NULL) {
vv=curr->index;wei=curr->weight; if(distD[uu]+wei
next; } } for(i=1;i<=v;++i) if(distD[i]==inf) { printf("No Answer\n"); return ; } sum=0; for(i=1;i<=v;++i) sum+=w[i]*distD[i]; printf("%I64d\n",sum); } */

  

转载于:https://www.cnblogs.com/mjc467621163/archive/2011/07/22/2114493.html

你可能感兴趣的文章
JavaScript案例一:Window弹窗案例
查看>>
当Ext.js中xtype: 'checkboxfield'时,没勾选则向后台发送的数据没有字段的解决方法...
查看>>
转载 《TypeScript 类型定义 DefinitelyTyped》
查看>>
Latent Dirichlet Allocation(LDA)
查看>>
hihocoder 1388 Periodic Signal
查看>>
MYSQL 开发技巧
查看>>
服务端的流水线
查看>>
ELK架构浅析
查看>>
UI4_UIWebView
查看>>
并查集
查看>>
centos从安装到环境配置
查看>>
只让类访问, 而不让类的实例来访问某个成员变量
查看>>
Python学习笔记第二十四周(JavaScript补充)
查看>>
动态规划-hdoj-4832-百度之星2014初赛第二场
查看>>
html中#include file的使用方法
查看>>
SQL Server里的 ISNULL 与 NULLIF
查看>>
STM32F1移植UCOSII
查看>>
js和jquery的区别
查看>>
fjnuoj 1004 游戏 (博弈论)
查看>>
Java语法基础常见疑惑解答
查看>>