1343 运输线(最短路)

本文介绍了一道竞赛题目,通过一位高一OIer女孩的提示,发现了解题的关键在于运用最短路算法。文章提供了完整的代码实现,并详细解释了如何构建图结构、计算节点间距离及运行最短路径算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


描述: 某次校赛,倒数第二难的题(按AC人数来看)。

没转过脑筋来看的话,确实有点无从下手。之后问了一个很巨的的高一OIer女孩,

她把案例给我比划了下,让我跑个最短路就好,我想了想,好像还真是这么回事。(Orz,不亏是北大冬令营选手)= =

感觉没她提示,我怎么也想不到是最短路啊。同时也问了快毕业的lx学长,虽然他已经记不得题意,但从他的code里分析就是如此。



#include <iostream>    
#include <algorithm>    
#include <vector>    
#include <queue>    
#include <cstring>   
using namespace std;     
#define mp make_pair    
#define pb push_back    
#define fi first    
#define se second    
#define rep(i,a,n) for(int i=a;i<n;i++)    
#define sz(a) (int)(a).size() 
typedef pair<int,int> PII; 
const int maxn = 1e3+10;     
const int INF = 0x3f3f3f3f;    
// head      
  
int w,h,n;    
int d[maxn];      
vector<PII> E[maxn];         
struct pos {     
    int x1, y1, x2, y2;    
    pos(int _x1=0,int _y1=0,int _x2=0,int _y2=0):x1(_x1),y1(_y1),x2(_x2),y2(_y2){}    
    void read() {cin >> x1 >> y1 >> x2 >> y2;}     
}p[maxn];    
    
void solve(int s, int t) {    
    memset(d, INF, sizeof(d));      
    d[0] = 0;      
    priority_queue<PII> q;      
    q.push(mp(-d[s], s));        
    while(!q.empty()) {      
        int now = q.top().se;     
        if(now == t) return;    
        q.pop();      
        rep(i, 0 ,sz(E[now])) {      
            int next = E[now][i].fi;      
            if(d[next] > d[now] + E[now][i].se) {      
                d[next] = d[now] + E[now][i].se;      
                q.push(mp(-d[next], next));      
            }       
        }      
    }      
}      
int value(pos a,pos b) {     
     if(a.x1 > b.x1)  swap(a, b);     
     if(a.x2 >= b.x1)        
        return min(abs(b.y1-a.y2), abs(a.y1-b.y2)) - 1;     
     if((a.y2 >= b.y1 && a.y2 <= b.y2) || (a.y1 <= b.y2 && a.y2 >= b.y2))     
       return b.x1 - a.x2 - 1;    
      int tem = min(abs(b.y1 - a.y2), abs(a.y1 - b.y2));  
      return max(tem, b.x1 - a.x2) - 1;     
 }  
    
 int main(void) {     
    cin >> w >> h >> n;     
    for(int i = 1; i <= n; i++) {    
        p[i].read();    
    }    
    p[0] = pos(-1, -1, -1, INF);    
    p[n + 1] = pos(w, -1, w, INF);    
     for(int i = 0; i <= n + 1; i++)     
         for(int j = 0; j < i; j++) {    
                int v = value(p[i], p[j]);    
                E[i].pb(mp(j, v));    
                E[j].pb(mp(i, v));    
         }    
    solve(0, n + 1);    
    cout << d[n + 1] << endl;     
    return 0;    
}     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值