以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 }