标签:color this data can 直接 iostream 选择 bsp stream
题意:
n个点,m条固定边,k条可选边,可选边最多只能选择一条,也可以不选择,问起点s到终点t的最小权值是什么?
题解:
1.正确的解法:
以起点终点为源点,求固定边最短路,然后对于k条可选边,比如可选边为起点p,终点q,则含有本条可选边的最优路径的距离为ds[p]+dt[q]+w(w为可选边权值,ds[p]为p到起点最短距离,dt[q]为q到终点最短距离)
复杂度:mlogn+k
2.歪解:
自己写看到这道题n只有500,m只有1000,直接求K次最短路,暴力求解,之后过了。。。。。。
坑点:
每组数据输出时中间隔一行,最后一组数据之后不要空行
代码:
#include<iostream> using namespace std; #include<cstdio> #include<cstdlib> #include<vector> #define MAXN 1000 #include<vector> #include<queue> typedef long long LL; struct teamdata{ LL d;LL point; bool operator<(const teamdata& pt)const{ return this->d>pt.d; } }; struct bian{ LL d,point; }; LL n,m,k,l,s,t; LL pre[MAXN]; vector<LL> ansl; vector<bian> maps[MAXN]; const LL inf=0x3f3f3f3f; LL d[MAXN]; queue<teamdata> team; LL SPFA(LL s,LL t){ LL ans=-1; teamdata pt;pt.d=0;pt.point=s; while(!team.empty()) team.pop(); team.push(pt);teamdata pd; for (LL i=0;i<=MAXN-10;i++) d[i]=inf,pre[i]=-1;d[s]=0; while(!team.empty()){ pt=team.front();team.pop(); if (pt.d>d[pt.point]) continue; if (pt.point==t){ ans=pt.d;continue; } for (LL i=0;i<maps[pt.point].size();i++){ LL nb=maps[pt.point][i].point; if (d[nb]>pt.d+maps[pt.point][i].d){ d[nb]=pt.d+maps[pt.point][i].d; pre[nb]=pt.point; pd.d=d[nb];pd.point=nb;team.push(pd); } } } return ans; } int main(){ int sp=0; while(scanf("%lld%lld%lld",&n,&s,&t)!=EOF){ sp++; if (sp>1) putchar(‘\n‘); scanf("%lld",&m); bian pt; for (int i=0;i<=n;i++) maps[i].clear(); for (LL i=0;i<m;i++){ LL p,q,k; scanf("%lld%lld%lld",&p,&q,&k); pt.d=k;pt.point=q; maps[p].push_back(pt); pt.point=p; maps[q].push_back(pt); } scanf("%lld",&k); LL zans=SPFA(s,t); ansl.clear(); LL x=t; while(x>0) { ansl.push_back(x); x=pre[x]; } LL bj=-1,bjm=-1; for (LL i=0;i<k;i++){ LL p,q,k; scanf("%lld%lld%lld",&p,&q,&k); bian pt;pt.d=k;pt.point=q; maps[p].push_back(pt); pt.point=p; maps[q].push_back(pt); LL zz=SPFA(s,t); if (zz<zans&&zz>=0) { zans=zz; if (pre[q]==p) bj=p,bjm=q; else bj=q,bjm=p; ansl.clear(); LL x=t; while(x>0) { ansl.push_back(x); x=pre[x]; } } maps[p].pop_back(); maps[q].pop_back(); } int ppt=-1,used=0; for (LL i=ansl.size()-1;i>=0;i--){ printf("%lld",ansl[i]); if (i>0) putchar(‘ ‘); if (bjm==ansl[i]&&bj==ppt) used=1; ppt=ansl[i]; } putchar(‘\n‘); if (used){ printf("%lld\n",bj); } else{ printf("Ticket Not Used\n"); } printf("%lld\n",zans); } return 0; }
标签:color this data can 直接 iostream 选择 bsp stream
原文地址:http://www.cnblogs.com/xfww/p/7620554.html