1 条题解
-
0
自动搬运
来自洛谷,原作者为

天南月
又是一个AFO的有害垃圾搬运于
2025-08-24 21:52:21,当前版本为作者最后更新于2019-08-12 22:14:27,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
在讲题之前,先发一发牢骚:强烈谴责出题人语义不清QAQ!!!在看到这一道题的一开始,我对照样例和题目看了老久,以为出题人的意思是选择一条最短路,使得除了这条路径上的所有边,这条路上的其他点的其他出边都要被损毁,这样的话就是一个费用计算方式比较与众不同的最小费用最短路,为此我还推了1个小时费用计算公式。满怀信心的交上去,结果......20分?!仅过了样例!!!
把数据点2下下来一看:原来不是路径上的经过点的出边,而是所有非最短路上的边都要求损毁!!!
于是这就变成一个极其容易的最小费用最短路问题了。先把所有未损毁的边的数量统计下来,记一个ans,接着把损毁边(0)的费用设为1(容易理解),把未损毁边(1)的费用设为-1(看下去就理解了),最终答案就是;
接下来上代码:
#include<bits/stdc++.h> using namespace std; int read(){ int x=0; char c=getchar(); while(!isdigit(c))c=getchar(); while(isdigit(c))x=x*10+c-48,c=getchar(); return x; } const int N=1e5+5,INF=1061109567; struct edge{ int next,to,opt; }e[N]; int n,m,tot,ans; int dis[N],head[N],cost[N]; bool vis[N]; void add(int x,int y,int opt){ e[++tot]=(edge){head[x],y,opt}; head[x]=tot; e[++tot]=(edge){head[y],x,opt}; head[y]=tot; } void Spfa(){ memset(dis,0x3f,sizeof(dis)); memset(cost,0x3f,sizeof(cost)); queue<int>q; q.push(1); dis[1]=0; vis[n]=true; cost[1]=0; while(!q.empty()){ int now=q.front(); q.pop(); vis[now]=false; for(int i=head[now],nxt;i;i=e[i].next){ if(dis[nxt=e[i].to]>dis[now]+1){ dis[nxt]=dis[now]+1; if(e[i].opt)cost[nxt]=cost[now]-1; else cost[nxt]=cost[now]+1; if(!vis[nxt])vis[nxt]=true,q.push(nxt); } else if(dis[nxt]==dis[now]+1){ if(e[i].opt){ if(cost[nxt]>cost[now]-1){ cost[nxt]=cost[now]-1; if(!vis[nxt])vis[nxt]=true,q.push(nxt); } } else{ if(cost[nxt]>cost[now]+1){ cost[nxt]=cost[now]+1; if(!vis[nxt])vis[nxt]=true,q.push(nxt); } } } } } } int main(){ n=read();m=read(); int a,b,c; for(int i=1;i<=m;++i){ a=read();b=read();c=read(); add(a,b,c); ans+=c; } Spfa(); printf("%d",ans+cost[n]); return 0; }数据比较水,跑个SPFA只要15ms...
- 1
信息
- ID
- 2701
- 时间
- 500ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者