[PA2012] Tax

传送门:>Here<

题意:给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价。起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权N<=100000 M<=200000

解题思路

不免要吐槽一下这题的数据,久调一下午无果与标程对拍没有任何差错不知道为什么就是WA 既然极限数据已经和标程拍上了那么权当出了吧……

不过还是一道好题

首先考虑这道题暴力的做法——将每条边作为新图的点,然后枚举原图的点,遍历一遍这个点相邻的所有边,按照大小打擂在新图中连边,但是这样边的数量多达$M^2$

可以考虑优化边的数量,用到差分的思想——以其中一条边作为基准,往上走要加,往下走不加。作为基准的这一条边也就是当前路径的入边,至于出边,只需要沿着差分的边走就可以了。于是我们所需要做的就是将每个点相邻的所有边排序,并且相邻的连边——大的往小的权值为0,小的往大的权值为差值。并且对于每一条边,它的反向边应当与它连一条权值为其本身的边,作为基准嘛

Code

/*By DennyQi 2018.8.11*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define  r  read()
#define  lr lread()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = 2000010;
const int MAXM = 2000010;
const int INF = 1e18;
inline int read(){
    int x = 0; int w = 1; register int c = getchar();
    while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
    if(c == '-') w = -1, c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * w;
}
inline int lread(){
    ll x = 0; int w = 1; register int c = getchar();
    while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
    if(c == '-') w = -1, c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * w;
}
struct Edge{
    ll len;
    int idx;
}e[MAXM];
struct Dij{
    ll w;
    int idx;
};
inline bool operator < (const Dij& a, const Dij& b){
    return a.w > b.w;
}
int N,M,x,y,S,T,v,top;
int pfirst[MAXM],pnxt[MAXM],pto[MAXM],pnum_edge=-1;
ll pcost[MAXM],cost[MAXM],z;
int first[MAXM],nxt[MAXM],to[MAXM],num_edge=-1;
ll d[MAXM];
bool vis[MAXM];
priority_queue <Dij> q;
inline bool comp(const Edge& a, const Edge& b){
    return a.len < b.len;
}
inline void add(int u, int v, int w){
//    printf("%lld->%lld(%lld)\n",u,v,w);
    to[++num_edge] = v;
    cost[num_edge] = w;
    nxt[num_edge] = first[u];
    first[u] = num_edge;
}
inline void padd(int u, int v, int w){
    pto[++pnum_edge] = v;
//    printf("num(%lld): %lld->%lld(%lld)\n",pnum_edge,u,v,w);
    pcost[pnum_edge] = w;
    pnxt[pnum_edge] = pfirst[u];
    pfirst[u] = pnum_edge;
    if(u == 1){
        add(S, pnum_edge, w);
    }
    if(v == N){
        add(pnum_edge, T, w);
    }
}
inline void Dijkstra(int s){
    for(int i = 0; i <= T; ++i) d[i] = INF;
    d[s] = 0;
    q.push((Dij){0,s});
    ll u,v;
    while(!q.empty()){
        u = q.top().idx; q.pop();
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = first[u]; i != -1; i = nxt[i]){
            v = to[i];
            if(d[u] + cost[i] < d[v]){
                d[v] = d[u] + cost[i];
                q.push((Dij){d[v],v});
            }
        }
    }
}
int main(){
//    freopen(".in","r",stdin);
//    freopen("qxz.out","w",stdout);
    N = r, M = r;
    memset(pfirst,-1,sizeof(pfirst));
    memset(first,-1,sizeof(first));
    S = M*2+1;
    T = M*2+2;
//    printf("S = %lld  T = %lld\n",S,T);
    for(int i = 1; i <= M; ++i){
        x = r, y = r, z = lr;
        padd(x, y, z);
        padd(y, x, z);
    }
    int v;
    for(int x = 2; x < N; ++x){
        top = 0;
        for(int i = pfirst[x]; i != -1; i = pnxt[i]){
            e[++top] = (Edge){pcost[i], i};
        }
        sort(e+1,e+top+1,comp);
        for(int i = 1; i <= top; ++i){
            if(i < top){
                add(e[i].idx, e[i+1].idx, e[i+1].len-e[i].len);
            }
            if(i > 1){
                add(e[i].idx, e[i-1].idx, 0);
            }
            add(e[i].idx^1, e[i].idx, e[i].len);
        }
    }
    Dijkstra(S);
    printf("%lld", d[T]);
    return 0;
}

 

转载于:https://www.cnblogs.com/qixingzhi/p/9463737.html

SELECT a.company_code, a.company_name, a.gl_account_nbr, a.clearing_date, a.clear_account_document_nbr, a.doc_assignment, a.fiscal_year, a.gl_document_nbr, a.document_item_nbr, a.doc_posting_date, a.document_date, a.document_currency, a.doc_reference, a.document_type, a.fiscal_period, a.doc_posting_key, a.doc_account_debit_or_credit, a.business_scope, a.doc_tax_code, a.doc_local_currency_amount, a.doc_currency_amount, a.tax_amount_standard, a.doc_currency_tax, a.doc_item_text, a.doc_source_order_nbr, a.plant_code, a.cost_center, a.doc_payment_starting_date, a.doc_open_item_management, a.doc_value_date, a.bpm_order_no, a.process_code, a.paymethod, a.paystract, a.zshare_ctr, a.cl_document_nbr, a.handling_accountant, a.handling_accountant_name, a.z_proid, a.pernr, a.dr_amount, a.cr_amount, a.paymethod_name, a.gl_account_name, a.anti_accounting_mark, a.enter_time, a.wb_debit_amount, a.wb_crebit_amount, a.ts_ms, a.cnt FROM ( SELECT a_1.company_code, a_1.company_name, a_1.gl_account_nbr, a_1.clearing_date, a_1.clear_account_document_nbr, a_1.doc_assignment, a_1.fiscal_year, a_1.gl_document_nbr, a_1.document_item_nbr, a_1.doc_posting_date, a_1.document_date, a_1.document_currency, a_1.doc_reference, a_1.document_type, a_1.fiscal_period, a_1.doc_posting_key, a_1.doc_account_debit_or_credit, a_1.business_scope, a_1.doc_tax_code, a_1.doc_local_currency_amount, a_1.doc_currency_amount, a_1.tax_amount_standard, a_1.doc_currency_tax, a_1.doc_item_text, a_1.doc_source_order_nbr, a_1.plant_code, a_1.cost_center, a_1.doc_payment_starting_date, a_1.doc_open_item_management, a_1.doc_value_date, a_1.bpm_order_no, head.procode AS process_code, payment.paymethod, a_1.paystract, a_1.zshare_ctr, a_1.cl_document_nbr, CASE WHEN head.pernrjb IS NOT NULL AND head.pernrjb <> ‘’::text THEN head.pernrjb ELSE bkpf.usnam END AS handling_accountant, pa001.sname AS handling_accountant_name, head.proid AS z_proid, head.pernr, a_1.dr_amount, a_1.cr_amount, payment.paymethodtxt AS paymethod_name, a_1.gl_account_name, a_1.anti_accounting_mark, a_1.enter_time, a_1.wb_debit_amount, a_1.wb_crebit_amount, a_1.ts_ms, row_number() OVER (PARTITION BY a_1.company_code, a_1.gl_account_nbr, a_1.fiscal_year, a_1.fiscal_period, a_1.gl_document_nbr, a_1.document_item_nbr ORDER BY head.procode DESC) AS cnt FROM table_01 a_1 LEFT JOIN dwd_ztbpm_payment_view payment ON a_1.bpm_order_no = payment.orderno LEFT JOIN dwd_ztfi_trpay_view trpay ON a_1.bpm_order_no = trpay.orderno LEFT JOIN dwd_bkpf_r bkpf ON bkpf.bukrs = a_1.company_code AND bkpf.gjahr = a_1.fiscal_year AND bkpf.belnr = a_1.gl_document_nbr LEFT JOIN dwd_ztbpm_post_head_r head ON a_1.bpm_order_no = head.orderno LEFT JOIN dwd_pa0001_r pa001 ON pa001.pernr = head.pernrjb) a WHERE a.cnt = 1 用rownumber会导致sql运行较慢,该怎么改能让sql运行快一点且数据结果与之前保持一致 改完后的sql具体给我写一下
最新发布
03-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值