• [NOI2019]回家路线


    LOJ3156

    题面就不放了 , 放一下数据范围 .

    看到 (n<=2000,m<=4000) 就想到直接 (dfs) 到底 , 居然就过了前 (4)个 样例 , 最后一个要 (2s) . 后来写了 (A=B=0)(5) 分 , 我知道写的是错的 , 还是交了以下这份代码 . ( LOJ 数据应该是官方数据 ) 得分 (70) .

    晚上到 LOJ 上一测 , 发现如果直接跑我的暴力有 (80) 分 , 又到 (AC) 记录里面随便看了一篇比较优秀的 , 改在后面 .

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cassert>
    #include<queue>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define Debug(x) cout<<#x<<"="<<x<<endl
    using namespace std;
    typedef long long LL;
    const int INF=1e9+7;
    inline LL read(){
        register LL x=0,f=1;register char c=getchar();
        while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
        while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
        return f*x;
    }
    
    const int N=100005;
    const int M=200005;
    
    struct Edge{
        int v,s,t,nxt;
    }e[M];
    int first[N],Ecnt=0;
    inline void Add_edge(int u,int v,int s,int t){
        e[++Ecnt]=(Edge){v,s,t,first[u]};
        first[u]=Ecnt;
    }
    
    int n, m, A, B, C;
    
    inline LL calc(int x){
    	return 1ll * A * x * x + 1ll * B * x + C;
    }
    
    namespace baoli{
    	LL ans = INF;
    	inline void dfs(int u, int time, LL cost){
    		if(u == n){
    			ans = min(ans, cost + time);
    		}
    		for(int i = first[u]; i; i = e[i].nxt){
    			int v = e[i].v, s = e[i].s, t = e[i].t;
    			if(s < time) continue;
    			dfs(v, t, cost + calc(s - time));
    		}
    	}
    	inline void main(){
    		dfs(1, 0, 0);
    		printf("%lld
    ", ans);
    		exit(0);
    	}
    };
    
    namespace Subtask1{ // A == 0 && B == 0
    	int dis[N], time[N];
    	queue <int> q;
    	LL ans = INF;
    	inline void Return(LL ans){
    		printf("%lld
    ", ans);
    		exit(0);
    	}
    	inline void main(){
    		q.push(1);
    		memset(dis, 0x3f, sizeof dis);
    		dis[1] = 0;
    		while(!q.empty()){
    			int u = q.front(); q.pop();
    			for(int i = first[u]; i; i = e[i].nxt){
    				int v = e[i].v;
    				if(time[u] > e[i].s) continue;
    				if(dis[u] + 1 < dis[v]){
    					dis[v] = dis[u] + 1;
    					time[v] = e[i].t;
    					q.push(v);
    
    				}
    				if(v == n) ans = min(ans, 1ll * (dis[u] + 1 + 1) * C + e[i].t);
    			}
    		}
    		Return(ans);
    		assert(false);
    	}
    	/*inline void main(){
    		q.push((Node){1, 0, 0});
    		while(!q.empty()){
    			int u = q.front().x, d = q.front().dis, t = q.front().time; q.pop();
    			for(int i = first[u]; i; i = e[i].nxt){
    				int v = e[i].v;
    				if(e[i].t < t) continue;
    				if(
    			}
    		}
    	}*/
    };
    
    int main(){
    #ifndef file
        freopen("route.in","r",stdin);
        freopen("route.out","w",stdout);
    #endif
    	n = read(), m = read(), A = read(), B = read(), C = read();
    	for(register int i = 1; i <= m; ++i){
    		register int x = read(), y = read(), p = read(), q = read();
    		Add_edge(x, y, p, q);
    	}
    	if(n <= 2000 && m <= 4000) 
    		baoli::main();
    	if(A == 0 && B == 0) Subtask1::main();
    }
    
    

    LOJ上的一份AC代码

    我没注意到时间 (q<=1000) , 这样的话 (O(nq)=O(1e8)) 应该可以卡过?
    直接 (dp) 有人得了 95分 . 把列车 按照时间排序 , 再依次更新 , 这样 (1e8) 就跑不满 , 直接就过了 . 可以用 (vector) 存状态 .
    对于这个数据范围就当 (O(nq)) 是正解好了 .

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define Debug(x) cout<<#x<<"="<<x<<endl
    using namespace std;
    typedef long long LL;
    const LL INF=1e18+7;
    inline LL read(){
        register LL x=0,f=1;register char c=getchar();
        while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
        while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
        return f*x;
    }
    
    const int N = 1e5 + 5;
    const int M = 2e5 + 5;
    
    struct Node{
    	int x, y, p, q;
    }a[M];
    inline bool cmp1(Node a, Node b){
    	if(a.p == b.p) return a.q < b.q;
    	return a.p < b.p;
    }
    
    vector <LL> f[N];
    vector <int> t[N];
    int n, m, A, B, C;
    
    inline LL calc(int x){
    	return 1ll * A * x * x + 1ll * B * x + C;
    }
    
    int main(){
    #ifndef file
        freopen("route.in","r",stdin);
        freopen("route.out","w",stdout);
    #endif
    	n = read(), m = read(), A = read(), B = read(), C = read();
    	for(int i = 1; i <= m; ++i){
    		a[i].x = read(), a[i].y = read(), a[i].p = read(), a[i].q = read();
    	}
    	sort(a + 1, a + m + 1, cmp1);
    
    	f[1].push_back(0), t[1].push_back(0);
    	for(int i = 1; i <= m; ++i){
    		int x = a[i].x, y = a[i].y, p = a[i].p, q = a[i].q;
    		int tt = -1;
    		for(int j = 0; j < t[y].size(); ++j)
    			if(t[y][j] == q) {tt = j; break;}
    		for(int j = 0; j < f[x].size(); ++j){
    			if(t[x][j] > p) continue;
    			int len = p - t[x][j];
    			if(tt == -1){
    				f[y].push_back(f[x][j] + calc(len));
    				t[y].push_back(q);
    				tt = f[y].size() - 1;
    			}
    			else if(f[x][j] + calc(len) < f[y][tt]){
    				f[y][tt] = f[x][j] + calc(len);
    			}
    		}
    	}
    	LL ans = INF;
    	for(int i = 0; i < f[n].size(); ++i)
    		ans = min(ans, f[n][i] + t[n][i]);
    	printf("%lld
    ", ans);
    }
    
    
  • 相关阅读:
    oracle行转列
    JVM设置空间大小
    Spring AOP 业务权限管理
    清晨漫步
    pull解析xml(android)
    今昔何昔
    Spring: Document root element "beans", must match DOCTYPE root "null
    xfire
    心之所向
    Oracle数据库连接
  • 原文地址:https://www.cnblogs.com/lizehon/p/11197337.html
Copyright © 2020-2023  润新知