zoukankan      html  css  js  c++  java
  • 1473E. Minimum Path(最短路+三维DP)

    给出一个无向带权图。

    定义一条路径的长度为:

    (sum_{i=1}^kw_{e_i}-max_{i=1}^kw_{e_i}+min_{i=1}^kw_{e_i})

    询问1号点到每个点的最短路径。

    (Solution)

    没见过的套路,比赛时确实是做不了。

    但是在2400分的题中应该很基础。

    可以把题意转化为,对于一条路径,可以支持两种操作:

    一种是减去一条边的边权。

    一种是将一条边的边权加2次。

    从而定义出状态(f(i,j,k))表示从起点到地(i)个点,是否执行了操作1,是否执行了操作2。

    这样就可以表示出所有的状态。每个点的答案就是(f(i,1,1))

    (Dijkstra)的本质是(DP),这道题之后对于最短路和(DP)的理解更加深刻了。

    //f(i,j,k)表示到第i个点的时候
    //是否执行第1次操作
    //是否执行第2次操作 
    //的最短路径 
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+100;
    const ll inf=1e18;
    struct node {
    	int u,v,w,nxt;
    }edge[maxn<<1];
    int head[maxn],tot;
    ll f[maxn][2][2];
    ll vis[maxn][2][2];
    int n,m;
    void addedge (int u,int v,int w) {
    	edge[tot].u=u;
    	edge[tot].v=v;
    	edge[tot].w=w;
    	edge[tot].nxt=head[u];
    	head[u]=tot++;
    	edge[tot].u=v;
    	edge[tot].v=u;
    	edge[tot].w=w;
    	edge[tot].nxt=head[v];
    	head[v]=tot++;
    }
    struct qnode {
    	int A,B,C;
    	ll w;
    	qnode (int AA,int BB,int CC,ll ww) {
    		A=AA;
    		B=BB;
    		C=CC;
    		w=ww;
    	}
    	bool operator < (const qnode &r) const {
    		return w>r.w;
    	}
    };
    void dij (int s) {
    	for (int i=0;i<=n;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) f[i][j][k]=inf;
    	f[s][0][0]=0;
    	priority_queue<qnode> q;
    	q.push(qnode(s,0,0,f[s][0][0]));
    	while (q.size()) {
    		qnode tt=q.top();
    		q.pop();
    		int A=tt.A;
    		int B=tt.B;
    		int C=tt.C;
    		if (vis[A][B][C]) continue;
    		long long dis=tt.w;
    		vis[A][B][C]=1; 
    		for (int i=head[A];i!=-1;i=edge[i].nxt) {
    			int v=edge[i].v;
    			if (!vis[v][B][C]&&dis+edge[i].w<f[v][B][C]) {
    				f[v][B][C]=dis+edge[i].w;
    				q.push(qnode(v,B,C,f[v][B][C]));
    			}
    			if (!B&&!vis[v][!B][C]&&dis<f[v][!B][C]) {
    				f[v][!B][C]=dis;
    				q.push(qnode(v,!B,C,f[v][!B][C]));
    			}
    			if (!C&&!vis[v][B][!C]&&dis+2*edge[i].w<f[v][B][!C]) {
    				f[v][B][!C]=dis+2*edge[i].w;
    				q.push(qnode(v,B,!C,f[v][B][!C]));
    			}
    			if (!B&&!C&&!vis[v][!B][!C]&&dis+edge[i].w<f[v][!B][!C]) {
    				f[v][!B][!C]=dis+edge[i].w;
    				q.push(qnode(v,!B,!C,f[v][!B][!C]));
    			}
    		}
    	}
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	for (int i=0;i<=n;i++) head[i]=-1;
    	for (int i=1;i<=m;i++) {
    		int u,v,w;
    		scanf("%d%d%d",&u,&v,&w);
    		addedge(u,v,w);
    	}
    	dij(1);
    	for (int i=2;i<=n;i++) printf("%lld ",f[i][1][1]);
    }
    
    
  • 相关阅读:
    fiddler抓取java系程序的网络通信
    ZOJ 2724 Windows Message Queue(优先队列)
    FZU 电动车通行证制度
    Havel定理
    Catch That Cow
    Trie树
    zoj 2876 Phone List
    zoj 2420
    getchar
    zoj 1315 Excuses, Excuses!
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14303207.html
Copyright © 2011-2022 走看看