请柬(spfa)
题目描述
在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。
这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。
输入输出格式
输入格式:
第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。
然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。
总部在第1个站点,价钱都是整数,且小于1000000000。
输出格式:
输出一行,表示最小费用。
输入输出样例
输入样例#1:
4 6 1 2 10 2 1 60 1 3 20 3 4 10 2 4 5 4 1 50
输出样例#1:
210
说明
【注意】
此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。
解题思路:
跑两遍spfa;
正着一边反着一边;
注意spfa的用法,时间复杂度为NE;
add函数为存储;
一定要记住spfa1
那个for循环有待解决;
代码如下
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 int m,n,k1=0,k2=0,x,y,z; 8 int head1[2000010],head2[2000010]; 9 int queue[4000010],qhead,qtail; 10 struct mmp 11 { 12 int to,next; 13 ll w; 14 }; 15 mmp e1[2000010],e2[2000010]; 16 ll dis[1000010],ans=0; 17 bool vis[1000100]; 18 void add1(int u,int v,ll w) 19 { 20 e1[++k1].next=head1[u]; 21 e1[k1].to=v; 22 e1[k1].w=w; 23 head1[u]=k1; 24 } 25 void add2(int u,int v,ll w) 26 { 27 e2[++k2].next=head2[u]; 28 e2[k2].to=v; 29 e2[k2].w=w; 30 head2[u]=k2; 31 } 32 void spfa1() 33 { 34 memset(vis,false,sizeof(vis)); 35 memset(dis,127,sizeof(dis)); 36 qhead=0; 37 qtail=1; 38 dis[1]=0; 39 vis[1]=true; 40 queue[1]=1; 41 while(qhead<qtail) 42 { 43 int p=queue[++qhead]; 44 vis[p]=false; 45 for(int i=head1[p];i;i=e1[i].next) 46 { 47 if(dis[e1[i].to]>dis[p]+e1[i].w) 48 {dis[e1[i].to]=dis[p]+e1[i].w; 49 if(vis[e1[i].to]==false) 50 { 51 vis[e1[i].to]=true; 52 queue[++qtail]=e1[i].to; 53 }} 54 } 55 } 56 for(int i=2;i<=n;i++) 57 ans+=dis[i]; 58 } 59 void spfa2() 60 { 61 memset(vis,false,sizeof(vis)); 62 memset(dis,127,sizeof(dis)); 63 qhead=0; 64 qtail=1; 65 dis[1]=0; 66 vis[1]=true; 67 queue[1]=1; 68 while(qhead<qtail) 69 { 70 int p=queue[++qhead]; 71 vis[p]=false; 72 for(int i=head2[p];i;i=e2[i].next) 73 { 74 if(dis[e2[i].to]>dis[p]+e2[i].w) 75 {dis[e2[i].to]=dis[p]+e2[i].w; 76 if(vis[e2[i].to]==false) 77 { 78 vis[e2[i].to]=true; 79 queue[++qtail]=e2[i].to; 80 } 81 } } 82 } 83 for(int i=2;i<=n;i++) 84 ans+=dis[i]; 85 } 86 int main() 87 { 88 //freopen("1342.txt","r",stdin); 89 scanf("%d%d",&n,&m); 90 for(int i=1;i<=m;i++) 91 { 92 scanf("%d%d%d",&x,&y,&z); 93 add1(x,y,z); 94 add2(y,x,z);} 95 spfa1(); 96 spfa2(); 97 printf("%lld",ans); 98 return 0; 99 }

浙公网安备 33010602011771号