最短路问题专题

Dijkstra

UVA 11374 Airport Express

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

先求从源汇点出发的最短路,枚举k条边,
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[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

你可能感兴趣的:(最短路问题专题)