最短路问题专题

Dijkstra

UVA 11374 Airport Express

n点m边的无向图,额外给k条边,走这k条边需要票(你只有一张),求s->t最短路,
n500,m1000,k1000

先求从源汇点出发的最短路,枚举k条边,
ans=min(f1(a)+w(a,b)+f2(b))

#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[n]<<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 (1000)
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 d1[MAXN],d2[MAXN],P1[MAXN],P2[MAXN];
int main()
{
//  freopen("uva11374.in","r",stdin);
//  freopen(".out","w",stdout);
    int n,S,T;
    bool flag=0;
    while(cin>>n>>S>>T) {
        if (flag) puts(""); flag=1; 
        S1.init(n);
        S--,T--;
        int m=read();
        For(i,m) {
            int x,y,z;
            cin>>x>>y>>z;
            S1.addedge2(x-1,y-1,z);
        }       
        S1.dijkstra(S);
        memcpy(d1,S1.d,sizeof(int)*n);
        memcpy(P1,S1.pnode,sizeof(int)*n);
        S1.dijkstra(T);
        memcpy(d2,S1.d,sizeof(int)*n);
        memcpy(P2,S1.pnode,sizeof(int)*n);
        int ans=d1[T],p=0,p2=0;

        m=read();
        For(i,m) {
            int x,y,z;
            cin>>x>>y>>z;
            x--,y--;
            if (d1[x]>d1[y]) swap(x,y);
            ll cost=(ll)d1[x]+d2[y]+z;
            if (cost < ans) {
                ans=cost; p = x+1; p2=y+1;
            }
        }

        vi v;
        if (!p) {
            v.pb(T);
            for(int u=P1[T];u!=-1;u=P1[u]) v.pb(u);
        }else {
            v.pb(p2-1);
            for(int u=P2[p2-1];u!=-1;u=P2[u]) v.pb(u);
            reverse(v.begin(),v.end());
            v.pb(p-1);
            for(int u=P1[p-1];u!=-1;u=P1[u]) v.pb(u);
        }
        int vs=SI(v);
        ForD(i,vs-1) cout<<v[i]+1<<' '; cout<<v[0]+1<<endl;     


        if (p) cout<<p<<endl; else puts("Ticket Not Used");
        cout<<ans<<endl;
    }



    return 0;
}

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[n]<<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边的无向带边权图,你需要删一条边,
使 ijdis(i,j) 最小

枚举起点,枚举删的边,跑dijkstra,复杂度 O(nm2logn)
对于某个起点i,删的边只有在最短路树上才会改变 jdis(i,j) ,所以复杂度降到 O(n2mlogn)

#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[n]<<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[n]<<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[n]<<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,bx<=dbda

#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[n]<<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[n]<<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

航空公司出售 NT20 张联票,要求从头坐,但可在中途任一站下飞机。
你有 NI20 份行程单,每份行程单上有若干城市,你在第一个城市,且希望按顺序游览城市,问最小花费,及该情况下的方案(保证唯一)。
每张票或行程单上的城市数 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[n]<<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[n]<<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[n]<<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[n]<<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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值