最短路问题专题
2016-04-01 18:56
197 查看
Dijkstra
UVA 11374 Airport Express
n点m边的无向图,额外给k条边,走这k条边需要票(你只有一张),求s->t最短路,n≤500,m≤1000,k≤1000n\le 500 ,m \le 1000,k \le 1000
先求从源汇点出发的最短路,枚举k条边,
ans=min(f1(a)+w(a,b)+f2(b))ans=min(f1(a)+w(a,b)+f2(b))
UVA 10917 Walk Through the Forest
gbn最近打算穿过一个森林,但是他比较傲娇,于是他决定只走一些特殊的道路,他打算只沿着满足如下条件的(A,B)道路走:存在一条从B出发回家的路,比所有从A出发回家的路径都短。你的任务是计算一共有多少条不同的回家路径。其中起点的编号为1,终点的编号为2.预处理出最短路,转DAG,dp
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } struct Edge{ int from,to,dist; }; struct HeapNode { int d,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (1010) struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXN]; int d[MAXN]; int p[MAXN]; //最短路中上一条边 int pnode[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void dijkstra(int s) { priority_queue<HeapNode> Q; Rep(i,n) d[i]=INF,pnode[i]=-1; d[s]=0; MEM(done) Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if (done[u]) continue; done[u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; pnode[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } } }S1; int n,m; vi G[MAXN]; int indegree[MAXN]; namespace topsort{ int b[MAXN]; int q[MAXN*4]; int topsort() { MEM(b) b[0]=1; int head_=1,tail=0; Rep(i,n) if (indegree[i]==0) { q[++tail]=i; } while (head_<=tail) { int now=q[head_]; int m=SI(G[now]); Rep(i,m) { int v=G[now][i]; indegree[v]--; b[v]+=b[now]; if (indegree[v]==0) { q[++tail]=v; } } head_++; } return b[1]; } } int main() { // freopen("uva10917.in","r",stdin); // freopen(".out","w",stdout); while(cin>>n &&n) { m=read(); S1.init(n); Rep(i,m) { int a=read()-1,b=read()-1; S1.addedge2(a,b,read()); } S1.dijkstra(1); Rep(i,n) indegree[i]=0,G[i].clear(); Rep(k,m) { int i=S1.edges[k*2].from,j=S1.edges[k*2].to; if (S1.d[i]>S1.d[j]) G[i].pb(j),indegree[j]++; else if (S1.d[i]<S1.d[j]) G[j].pb(i),indegree[i]++; } cout<<topsort::topsort()<<endl; } return 0; }
LA 4080 Warfare
给一张n点m边的无向带边权图,你需要删一条边,使∑i∑jdis(i,j)\sum_i\sum_jdis(i,j)最小
枚举起点,枚举删的边,跑dijkstra,复杂度O(nm2logn)O(nm^2logn)
对于某个起点i,删的边只有在最短路树上才会改变∑jdis(i,j)\sum_jdis(i,j),所以复杂度降到O(n2mlogn)O(n^2mlogn)
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (0x3f3f3f3f3f3f3f3f) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,L; struct Edge{ int from,to,dist; }; struct HeapNode { int d,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (100+10) #define MAXM (2000+10) struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXN]; ll d[MAXN]; int p[MAXN]; //最短路中上一条边 int pnode[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } ll dijkstra(int s,int E = -1 ) { priority_queue<HeapNode> Q; Rep(i,n) d[i]=INF,pnode[i]=-1,p[i]=-1; d[s]=0; MEM(done) Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if (done[u]) continue; done[u]=1; int mm=G[u].size(); Rep(i,mm) { if (E!=-1&&E/2==G[u][i]/2) continue; Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; pnode[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } ll ans=0; Rep(i,n) ans+=(INF == d[i] ) ? L : d[i] ; return ans; } ll T[MAXM]; // the cost if delete ith edge int p2[MAXN]; //最短路中上一条边 void calc(int s){ //only consider started at Point s ll c=dijkstra(s); Rep(i,m+1) T[i]+=c; memcpy(p2,p,sizeof(int)*n); Rep(i,n) if (p2[i]!=-1) { T[p2[i]|1]+= dijkstra(s,p2[i])-c; } } void solve(){ MEM(T) Rep(i,n) calc(i); ll ans=T[0]; Rep(i,m) ans=max(ans,T[i]); cout<<T[m]<<' '<<ans<<endl; } }S1; int main() { // freopen("uva1416.in","r",stdin); // freopen(".out","w",stdout); while(cin>>n>>m>>L) { S1.init(n); Rep(i,m) { int a=read()-1,b=read()-1; S1.addedge2(a,b,read()); } S1.solve(); } return 0; }
UVA 10537 The Toll! Revisited
从s到t,每次经过一个村庄要缴纳1个单位的货物,经过一个城镇时,每20个货物就要缴纳一个(不足向上取整),求字典序最小的最少花费路径。从终点向起点走Dijkstra。
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (0x3f3f3f3f3f3f3f3f) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,h[1000]; char h2[1000]; void prework(){ Fork(i,'a','z') h[i]=i-'a',h2[i-'a']=i; Fork(i,'A','Z') h[i]=i-'A'+26,h2[i-'A'+26]=i; } struct Edge{ int from,to,dist; }; struct HeapNode { int d,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (100) struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXN]; ll d[MAXN]; int p[MAXN]; //最短路中上一条边 int pnode[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void dijkstra(int s,ll w) { priority_queue<HeapNode> Q; Rep(i,n) d[i]=INF,pnode[i]=-1; d[s]=w; MEM(done) Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if (done[u]) continue; done[u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (e.from<26) e.dist=1; else { e.dist=d[u]/19; while((d[u]+e.dist)-ceil(((double)d[u]+e.dist)/20)<d[u]) ++e.dist; } if (d[e.to]>d[u]+e.dist|| (d[e.to]==d[u]+e.dist&&h2[pnode[e.to]]>h2[u]) ) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; pnode[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } } }S1; int main() { // freopen("uva10537.in","r",stdin); // freopen(".out","w",stdout); prework(); int kcase=1; while(cin>>n && n!=-1) { S1.init(26*2); For(i,n) { char a[2],b[2]; cin>>a>>b; S1.addedge2(h[a[0]],h[b[0]],0); } ll w; char st[2],ed[2]; cin>>w>>st>>ed; printf("Case %d:\n",kcase++); S1.dijkstra(h[ed[0]],w); printf("%lld\n",S1.d[h[st[0]]]); int u; for(u=h[st[0]];S1.pnode[u]!=-1;u=S1.pnode[u]) printf("%c-",h2[u]); cout<<h2[u]<<endl; } return 0; }
Bellman-Ford
UVA 11090 Going in Cycle!!
给定一个n点m边带正权有向图,求平均权值最小的回路,无解输’No cycle found’二分求解,注意无解当且仅当图中无环
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m; struct Edge{ int from,to; double dist; }; #define MAXN (1000) struct BellmanFord { int n,m; vector<Edge> edges; vi G[MAXN]; bool inq[MAXN]; double d[MAXN]; int cnt[MAXN],p[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } bool negativeCycle() { queue<int> Q; MEM(inq) MEM(cnt) Rep(i,n) d[i]=0,inq[i]=1,Q.push(i); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist ) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; if (!inq[e.to]) { Q.push(e.to); inq[e.to]=1; if (++cnt[e.to]>n) return 1; } } } } return 0; } bool check(double x) { Rep(i,m) edges[i].dist -=x; bool ret = negativeCycle(); Rep(i,m) edges[i].dist +=x; return ret; } }S1; int main() { // freopen("uva11090.in","r",stdin); // freopen(".out","w",stdout); int T=read(); For(kcase,T) { cin>>n>>m; S1.init(n); For(i,m) { int a=read()-1,b=read()-1; S1.addedge(a,b,read()); } double L = 0 , R = 10000000; printf("Case #%d: ",kcase); if (!S1.check(R+1)) { puts("No cycle found."); continue; } while(R-L>1e-3) { double m= (L+R)/2; if (S1.check(m)) R=m; else L=m; } printf("%.2lf\n",R); } return 0; }
UVA 11478 Halum
已知带权有向图,每次可以选一个结点v和整数d,把终点为v的边的权值减d,起点为v的边的权值加d,求让所有边权的最小值非负且尽量大。设节点v上的d为sum_v
则, wa,b−x<=db−daw_{a,b}-x<=d_b-d_a
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m; struct Edge{ int from,to; double dist; }; #define MAXN (520) struct BellmanFord { int n,m; vector<Edge> edges; vi G[MAXN]; bool inq[MAXN]; double d[MAXN]; int cnt[MAXN],p[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } bool negativeCycle() { queue<int> Q; MEM(inq) MEM(cnt) Rep(i,n) d[i]=0,inq[i]=1,Q.push(i); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist ) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; if (!inq[e.to]) { Q.push(e.to); inq[e.to]=1; if (++cnt[e.to]>n) return 1; } } } } return 0; } bool check(double x) { Rep(i,m) edges[i].dist -=x; bool ret = negativeCycle(); Rep(i,m) edges[i].dist +=x; return !ret; } }S1; int main() { // freopen("uva11478.in","r",stdin); // freopen(".out","w",stdout); while(cin>>n>>m) { S1.init(n); For(i,m) { int a=read()-1,b=read()-1; S1.addedge(a,b,read()); } int L = 0 , R = 10001,ans = 0; if (S1.check(R+1)) { puts("Infinite"); continue; } else if (!S1.check(1)) { puts("No Solution"); continue; } while(L<=R) { int m= (L+R)/2; if (S1.check(m)) L=m+1,ans=m; else R=m-1; } printf("%d\n",ans); } return 0; }
建模
UVA 1078 Steam Roller
给一个R条横线与C条竖线组成的网格,线段带权表示通过时间,权为0的线段不能通过,求(r1,c1)->(r2,c2)的最短路。对于任意一条边,如果在进入这条边之前或离开这条边之后立即拐弯,通过时间翻倍,起点终点所在的时间翻倍,“时间加倍规则不叠加”。
拆点,(r,c,dir)表示(r,c)点有向dir趋势时的最短路,其中dir为4方向与静止。
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (60000) #define MAXR (100+10) int n,m; struct Edge{ int from,to,dist; }; struct HeapNode { int d,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXN]; int d[MAXN]; int p[MAXN]; //最短路中上一条边 int pnode[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void dijkstra(int s) { priority_queue<HeapNode> Q; Rep(i,n) d[i]=INF,pnode[i]=-1; d[s]=0; MEM(done) Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if (done[u]) continue; done[u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; pnode[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } } }S1; int R,C,r1,c1,r2,c2; int grid[MAXR][MAXR][5]; const int LEFT=0,RIGHT=1,DOWN=2,UP=3,STAY=4; int di[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; int id[MAXR][MAXR][5],siz=0; int ID(int i,int j,int k) { int &x = id[i][j][k]; if (!x) x=++siz; return x; } bool cango(int i,int j,int dir) { if (i<0||i>=R||j<0||j>=C) return 0; return grid[i][j][dir] >0; } int main() { // freopen("uva1078.in","r",stdin); // freopen(".out","w",stdout); int kcase=1; while(cin>>R>>C>>r1>>c1>>r2>>c2&&R ) { r1--,c1--,r2--,c2--; MEM(grid) Rep(i,R) { Rep(j,C-1) { grid[i][j][RIGHT]=grid[i][j+1][LEFT]=read(); } if (i!=R-1) Rep(j,C) { grid[i][j][DOWN]=grid[i+1][j][UP]=read(); } } S1.init(5*R*C+1); MEM(id) siz=0; Rep(i,R) Rep(j,C) { Rep(dir,4) { if (cango(i,j,dir^1)) { S1.addedge(ID(i,j,dir),ID(i,j,4),grid[i][j][dir^1]); if (cango(i,j,dir)) { S1.addedge(ID(i,j,dir),ID(i+di[dir][0],j+di[dir][1],dir),grid[i][j][dir]); } } if (grid[i][j][dir]) { S1.addedge(ID(i,j,4),ID(i+di[dir][0],j+di[dir][1],4),2*grid[i][j][dir]); S1.addedge(ID(i,j,4),ID(i+di[dir][0],j+di[dir][1],dir),2*grid[i][j][dir]); } } } S1.dijkstra(ID(r1,c1,4)); ll ans=S1.d[ID(r2,c2,4)]; printf("Case %d: ",kcase++); if (ans==INF) puts("Impossible"); else printf("%lld\n",ans); } return 0; }
UVA 1048 - Low Cost Air Travel
航空公司出售NT≤20NT\le20张联票,要求从头坐,但可在中途任一站下飞机。你有NI≤20NI\le20份行程单,每份行程单上有若干城市,你在第一个城市,且希望按顺序游览城市,问最小花费,及该情况下的方案(保证唯一)。
每张票或行程单上的城市数≤10\le 10
对每份行程单
把“目前所在城市,已经经过行程单上几个城市”作为节点建图
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int NT,NI,Q; #define MAXC (400+10) #define MAXL (20+10) int id[MAXC][MAXL],siz=0; int ID(int x,int y) { int &p =id[x][y]; if (!p) { id[x][y]=siz++; } return p; } vector<int> idx; int find(int x) { return lower_bound(idx.begin(), idx.end(), x) - idx.begin(); } vector<int> ticket[MAXL],trip[MAXL]; int w[MAXL],l[MAXL],l2[MAXL]; struct Edge{ int from,to,dist; }; struct HeapNode { int d,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (40000+10) struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[MAXN],Rid; bool done[MAXN]; int d[MAXN]; int p[MAXN]; //最短路中上一条边 int pnode[MAXN]; void addedge(int u,int v,int w,int rid){ edges.pb((Edge){u,v,w}); Rid.pb(rid); G[u].pb(m++); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); Rid.clear(); } void dijkstra(int s) { priority_queue<HeapNode> Q; Rep(i,n) d[i]=INF,p[i]=pnode[i]=-1; d[s]=0; MEM(done) Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if (done[u]) continue; done[u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; pnode[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } } void putedge(int e) { int u; vi ans; for(u=e;p[u]!=-1;u=pnode[u]) ans.pb(Rid[p[u]]); int mm=ans.size(); RepD(i,mm-1) printf(" %d",ans[i]); cout<<endl; } }S1; int main() { // freopen("uva1048.in","r",stdin); // freopen(".out","w",stdout); int kcase=1; while(cin>>NT && NT ) { MEM(id) siz=0; idx.clear(); For(i,NT) { w[i]=read(); l[i]=read(); ticket[i].clear(); For(j,l[i]) { int p=read(); ticket[i].pb(p); idx.pb(p); } } NI=read(); For(i,NI) { l2[i]=read(); trip[i].clear(); For(j,l2[i]) { int p=read(); trip[i].pb(p); idx.pb(p); } } sort(idx.begin(),idx.end()); int m=unique(idx.begin(),idx.end())-idx.begin(); For(i,NT) Rep(j,l[i]) ticket[i][j]=find(ticket[i][j]); For(i,NI) Rep(j,l2[i]) trip[i][j]=find(trip[i][j]); For(k,NI) { //枚举行程 S1.init(m*13); int sz = l2[k]; //行程城市数 For(i,NT) { //枚举票 int s = ticket[i][0]; Rep(pos1,sz) { //枚举当前城市 int pos2=pos1; For(j,l[i]-1) { int e = ticket[i][j]; if (e==trip[k][pos2]) pos2++; S1.addedge(ID(s,pos1),ID(e,pos2),w[i],i); if (pos2==sz) break; } } } S1.dijkstra(ID(trip[k][0],1)); int ans=S1.d[ID(trip[k][sz-1],sz)]; printf("Case %d, Trip %d: Cost = %d\n Tickets used:",kcase,k,ans); S1.putedge(ID(trip[k][sz-1],sz)); } ++kcase; } return 0; }
LA 3661 Animal Run
同BZOJ 1001解法略
UVA 10603 Fill
UVA 10269 Adventure of Super Mario
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m; int A,B,L,C; struct Edge{ int from,to,dist; }; struct HeapNode { int d,c,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (100+10) #define MAXC (10+10) int f[MAXN][MAXN]; void floyd() { Rep(k,A) Rep(i,n) Rep(j,n) f[i][j]=min((ll)f[i][j],(ll)f[i][k]+f[k][j]); } struct Dijkstra { int n,m,w[MAXN]; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXC][MAXN]; int d[MAXC][MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void dijkstra(int s,int e) { priority_queue<HeapNode> Q; MEMI(d) d[0][s]=0; MEM(done) Q.push((HeapNode){0,0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u,c=x.c; if (done[c][u]) continue; done[c][u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[c][e.to]>d[c][u]+e.dist) { d[c][e.to]=d[c][u]+e.dist; Q.push((HeapNode){d[c][e.to],c,e.to}); } } if (c<C) { Rep(i,n) if (f[u][i]<=L) { if (d[c+1][i]>d[c][u]) { d[c+1][i]=d[c][u]; Q.push((HeapNode){d[c+1][i],c+1,i}); } } } } cout<<d[C][e]<<endl; } }S1; int main() { // freopen("uva10269.in","r",stdin); // freopen(".out","w",stdout); int T=read(); while(T--) { cin>>A>>B>>m>>L>>C; n=A+B; S1.init(n); MEMI(f) For(i,m) { int a,b,c; scanf("%d%d%d",&a,&b,&c); --a;--b; S1.addedge2(a,b,c); f[a][b]=f[b][a]=min(f[a][b],c); } Rep(i,n) f[i][i]=0; floyd(); S1.dijkstra(n-1,0); } return 0; }
UVA 11367 Full Tank?
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m; struct Edge{ int from,to,dist; }; struct HeapNode { int d,c,u; bool operator< (const HeapNode& rhs) const { return d > rhs.d; } }; #define MAXN (1010) #define MAXC (100+10) struct Dijkstra { int n,m,w[MAXN]; vector<Edge> edges; vector<int> G[MAXN]; bool done[MAXC][MAXN]; int d[MAXC][MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void dijkstra(int s,int C,int e) { priority_queue<HeapNode> Q; MEMI(d) d[0][s]=0; MEM(done) Q.push((HeapNode){0,0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u,c=x.c; if (done[c][u]) continue; done[c][u]=1; int mm=G[u].size(); Rep(i,mm) { Edge e = edges[G[u][i]]; if (c<e.dist) continue; if (d[c-e.dist][e.to]>d[c][u]) { d[c-e.dist][e.to]=d[c][u]; Q.push((HeapNode){d[c-e.dist][e.to],c-e.dist,e.to}); } } if (c<C) { if (d[c+1][u]>d[c][u]+w[u]) { d[c+1][u]=d[c][u]+w[u]; Q.push((HeapNode){d[c+1][u],c+1,u}); } } } if (INF == d[0][e]) { puts("impossible"); } else { cout<<d[0][e]<<endl; } } }S1; int main() { // freopen("uva11367.in","r",stdin); // freopen(".out","w",stdout); while(cin>>n>>m) { S1.init(n); Rep(i,n) S1.w[i]=read(); For(i,m) { int a,b,c; scanf("%d%d%d",&a,&b,&c); S1.addedge2(a,b,c); } int q=read(); while(q--) { int c,s,e; scanf("%d%d%d",&c,&s,&e); S1.dijkstra(s,c,e); } } return 0; }
UVA 11280 Flying to Fredericton
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,s,e; struct Edge{ int from,to; double dist; }; #define MAXN (1000+10) #define MAXC (MAXN) struct BellmanFord { int n,m; vector<Edge> edges; vi G[MAXN]; bool inq[MAXC][MAXN]; int d[MAXC][MAXN]; int cnt[MAXN],p[MAXN]; void addedge(int u,int v,int w){ edges.pb((Edge){u,v,w}); G[u].pb(m++); } void addedge2(int u,int v,int w) { addedge(u,v,w);addedge(v,u,w); } void init(int _n){ n=_n; m = 0; Rep(i,n) G[i].clear(); edges.clear(); } void BF() { int C=n; queue<int> Q; queue<int> Q2; MEM(inq) MEM(cnt) inq[0][s]=1; Q.push(s); Q2.push(0); MEMI(d) Rep(i,n) d[0][s]=0; while(!Q.empty()) { int u = Q.front(); Q.pop(); int c = Q2 .front(); Q2.pop(); inq[c][u] = 0; int mm=G[u].size(); if (c<C) Rep(i,mm) { Edge e = edges[G[u][i]]; if (d[c+1][e.to]>d[c][u]+e.dist ) { d[c+1][e.to]=d[c][u]+e.dist; p[e.to]=G[u][i]; if (!inq[c+1][e.to]) { Q.push(e.to); Q2.push(c+1); inq[c+1][e.to]=1; } } } } For(i,C) d[i][e]=min(d[i][e],d[i-1][e]); } }S1; vector<string> idx; int find(string x) { return lower_bound(idx.begin(), idx.end(), x) - idx.begin(); } int main() { // freopen("uva11280.in","r",stdin); // freopen(".out","w",stdout); int T=read(); For(kcase,T) { if (kcase>1) puts(""); printf("Scenario #%d\n",kcase); n=read(); S1.init(n); idx.clear(); For(i,n) { string s; cin>>s; idx.pb(s); } sort(idx.begin(),idx.end()); m=read(); For(i,m) { string s1,s2; int c; cin>>s1>>s2>>c; S1.addedge(find(s1),find(s2),c); } int q=read(); s=find("Calgary"),e=find("Fredericton"); S1.BF(); while(q--) { int t=read(); ++t; t=max(t,0); t=min(t,-1+n); if (S1.d[t][e] == INF ) { puts("No satisfactory flights"); } else printf("Total cost of flight(s) is $%d\n",(int)S1.d[t][e]); } } return 0; }
相关文章推荐
- c++中this指针
- Appium中部分api的使用方法
- cocos2d-x 3.4版本 Android ndk-gdb真机调试环境搭建
- ubuntu--windows获取文件路径
- 链队列的基本操作
- KVM虚拟机发送IPI的流程
- memcached和redis的区别
- 工作一直没有进步怎么办?试试PDCA法则吧!
- mysql
- 你不知道的Spring配置文件
- 3D基础--Vertex
- mac下安装tomcat
- 【Python】Python的数据分析(三)——数据文件及数据结构
- UVA 1108 - Mining Your Own Business
- 9.应用程序如何访问驱动
- 云计算:利用叶子云桌面虚拟化管理平台搭建企业的桌面云,首次使用服务器组(四)
- LeetCode-3. Longest Substring Without Repeating Characters
- (9)IText读取PDF
- JQuery之动画与特效
- HTTP抓包的实践--协议