您的位置:首页 > 其它

最短路问题专题

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: