P1073 最优贸易 dp

以spfa为框架,将入队的条件改为当前节点有更优解即可。f[i]表示到i点的最小花费。

有的样例真的是水到一定程度了啊,非常严重的错误都可以跑过。。。

惨痛教训:无权图微改add_edge的同时也要改一下Edge结构体,否则照我的写法就会把ne赋给wi!

不过这道题还是挺简单的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 
 9 const int Maxn = 1e5+10,Maxm = 5e5+10;
10 
11 struct Edge{
12     int to,ne;
13 }edges[Maxm<<1];
14 
15 vector<int> g[Maxn];
16 int first[Maxn],f[Maxn],price[Maxn],inq[Maxn],ok[Maxn];
17 int n,m,a,b,c,ans,cnte;
18 
19 void add_edge(int fr,int to){
20     edges[++cnte] = (Edge){to,first[fr]};
21     first[fr] = cnte;
22     g[to].push_back(fr);
23 }
24 
25 void dfs(int s){
26     ok[s] = 1;
27     for(int i = 0;i < g[s].size();i++)
28         if(!ok[g[s][i]])dfs(g[s][i]);
29 }
30 
31 int main(){
32     scanf("%d%d",&n,&m);
33     for(int i = 1;i <= n;i++)scanf("%d",&price[i]);
34     for(int i = 1;i <= m;i++){
35         scanf("%d%d%d",&a,&b,&c);
36         add_edge(a,b);
37         if(c == 2)add_edge(b,a);
38     }
39     memset(f,0x3f,sizeof f);
40     queue<int> q;
41     q.push(1),inq[1] = true;
42     while(!q.empty()){
43         int u = q.front();q.pop();inq[u] = false;
44         for(int i = first[u];i;i = edges[i].ne){
45             int v = edges[i].to;
46             if(f[v] > min(f[u],price[u])){
47                 f[v] = min(f[u],price[u]);
48                 if(!inq[v])q.push(v),inq[v] = 1;
49             }
50         }
51     }
52     dfs(n);
53     for(int i = 1;i <= n;i++)
54         if(ok[i])ans = max(ans,price[i]-f[i]);
55     printf("%d",ans);
56 return 0;
57 }

猜你喜欢

转载自www.cnblogs.com/Wangsheng5/p/11782281.html