cogs1685 膜法森林 神奇的SPFA

继续填坑……链接:http://cogs.pro/cogs/problem/problem.php?pid=1685

题意:两种费用,求出两种费用最小的和。

正解是$LCT$……但是这里有一个令人惊掉下巴的做法……

不断枚举每一条边所需的第一种费用,对于满足这一条件下的边加入图中,同时将这条边两个端点压入队列,随后跑最短路,跑出一次更新一次最小值……

恩就这么做出来了……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=100005,maxm=100005;
 8 int fro[maxm],too[maxm],wei1[maxm],wei2[maxm],n,m,id[maxn],dis[maxn];
 9 queue<int>q;
10 int cmp(int a,int b)
11 {
12     return wei1[a]<wei1[b];
13 }
14 struct node
15 {
16     int from,to,dis,next;
17 }edge[maxm<<1];
18 int head[maxn],tot;
19 void addedge(int u,int v,int w)
20 {
21     edge[++tot]=(node){u,v,w,head[u]};head[u]=tot;
22 }
23 bool inqueue[maxn];
24 void spfa()
25 {
26     while(!q.empty())
27     {
28         int u=q.front();q.pop();inqueue[u]=0;
29         for(int i=head[u];i;i=edge[i].next)
30         {
31             int v=edge[i].to;
32             if(dis[v]>max(dis[u],edge[i].dis))
33             {
34                 dis[v]=max(dis[u],edge[i].dis);
35                 if(!inqueue[v])q.push(v),inqueue[v]=1;
36             }
37         }
38     }
39 }
40 int haha()
41 {
42     //freopen("magicalforest.in","r",stdin);
43     //freopen("magicalforest.out","w",stdout);
44     scanf("%d%d",&n,&m);
45     for(int i=1;i<=m;i++)
46     {
47         id[i]=i;
48         scanf("%d%d%d%d",&fro[i],&too[i],&wei1[i],&wei2[i]);
49     }
50     sort(id+1,id+m+1,cmp);
51     memset(dis,0x3f,sizeof(dis));
52     dis[1]=0;
53     int cur=1,ans=0x3f3f3f3f;
54     for(;cur<=m;)
55     {
56         int tmp=wei1[id[cur]];
57         while(wei1[id[cur]]==tmp)
58         {
59             addedge(fro[id[cur]],too[id[cur]],wei2[id[cur]]);
60             addedge(too[id[cur]],fro[id[cur]],wei2[id[cur]]);
61             q.push(fro[id[cur]]),q.push(too[id[cur]]);
62             inqueue[fro[id[cur]]]=inqueue[too[id[cur]]]=1;
63             cur++;
64         }
65         spfa();
66         if(dis[n]<0x3f3f3f3f)ans=min(ans,dis[n]+wei1[id[cur-1]]);
67     }
68     if(ans>=0x3f3f3f3f)ans=-1;
69     printf("%d\n",ans);
70 }
71 int sb=haha();
72 int main(){;}
cogs1685

 

posted @ 2017-08-11 21:18  ccc000111  阅读(156)  评论(0编辑  收藏  举报