(这个链接只是为了自己方便找,页面设置权限了,不要尝试访问)
(建议您从上方链接进入我的个人网站查看此 Blog,在 Luogu 中图片会被墙掉,部分 Markdown 也会失效)
是一道 DP + 最短路,赛时没想到 DP,嗯写了个 Dijk + 随机化微小扰动 + 卡时,当然最后寄掉了。
xxxxxxxxxx
1611
2
3
4
5
6/******************************
7abbr
8
9******************************/
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int percent){return rndd(1, 100) <= percent;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20
21bitset < 110 > wharf[22];
22int blocked[22];
23
24template<typename T = int>
25inline T read(void);
26
27struct Edge{
28 Edge* nxt;
29 int to;
30 int val;
31 void* operator new(size_t);
32 Edge(Edge* nxt, int to, int val):nxt(nxt), to(to), val(val){;}
33 Edge(void) = default;
34}eData[410];
35void* Edge::operator new(size_t){static Edge* P = eData; return ++P;}
36Edge* head[22];
37
38int N, M, K, E;
39
40bool vis[22];
41ll dis[22];
42void Dijk(int);
43
44priority_queue <
45 pair < ll, int > /*distance, vertex*/,
46 vector < pair < ll, int > >,
47 // [](pair < int, int > x, pair < int, int > y) ->bool{
48 // }
49 greater < pair < ll, int > >
50 > vert;
51int main(){
52 freopen("plan.in", "r", stdin);
53 freopen("plan.out", "w", stdout);
54 N = read(), M = read(), K = read(), E = read();
55 for(int i = 1; i <= E; ++i){
56 int f = read(), t = read(), val = read();
57 if(f == t)continue;
58 head[f] = new Edge(head[f], t, val);
59 head[t] = new Edge(head[t], f, val);
60 }
61 int D = read();
62 while(D--){
63 int p = read(), a = read(), b = read();
64 for(int i = a; i <= b; ++i)wharf[p][i] = true;
65 }
66 for(int i = 1; i <= M; ++i)blocked[i] = wharf[i]._Find_next(0);
67 ll ans(0);
68 ll lastcost(-1);
69 for(int i = 1; i <= N; ++i){
70 Dijk(i);
71 ll cost = dis[M];
72 ans += cost;
73 if(i != 1 && cost != lastcost)ans += K;
74 lastcost = cost;
75 }
76 while((double)clock() / CLOCKS_PER_SEC < 0.7){
77 for(int i = 1; i <= M; ++i){
78 for(auto j = head[i]; j; j = j->nxt){
79 if(rnddd(10))j->val *= 1.05;
80 }
81 blocked[i] = wharf[i]._Find_next(0);
82 }
83 ll anss(0);
84 ll lastcostt(-1);
85 for(int i = 1; i <= N; ++i){
86 Dijk(i);
87 ll costt = dis[M];
88 anss += costt;
89 if(i != 1 && costt != lastcostt)anss += K;
90 lastcostt = costt;
91 }
92 ans = min(ans, anss);
93 }
94 printf("%lld\n", ans);
95 // fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
96 return 0;
97}
98
99
100void Dijk(int day){
101 bool block[22];
102 memset(block, false, sizeof(block));
103 for(int i = 1; i <= M; ++i){
104 if(day == blocked[i]){
105 block[i] = true;
106 if(blocked[i] <= N)blocked[i] = wharf[i]._Find_next(blocked[i]);
107 }
108 }
109 memset(vis, false, sizeof(vis));
110 for(int i = 1; i <= M; ++i)dis[i] = LLONG_MAX / 2ll - 10ll;
111 dis[1] = 0ll;
112 vert.push(make_pair(dis[1], 1));
113 while(!vert.empty()){
114 int p;
115 tie(ignore, p) = vert.top();
116 vert.pop();
117 if(vis[p] || block[p])continue;
118 vis[p] = true;
119 for(auto i = head[p]; i; i = i->nxt){
120 if(dis[p] + i->val < dis[i->to]){
121 dis[i->to] = dis[p] + i->val;
122 if(!vis[i->to])vert.push(make_pair(dis[i->to], i->to));
123 }
124 }
125 }
126}
127
128template<typename T>
129inline T read(void){
130 T ret(0);
131 short flag(1);
132 char c = getchar();
133 while(c != '-' && !isdigit(c))c = getchar();
134 if(c == '-')flag = -1, c = getchar();
135 while(isdigit(c)){
136 ret *= 10;
137 ret += int(c - '0');
138 c = getchar();
139 }
140 ret *= flag;
141 return ret;
142}
143
144/*
145
1465 5 10 8
1471 2 1
1481 3 3
1491 4 2
1502 3 2
1512 4 4
1523 4 1
1533 5 2
1544 5 2
1554
1562 2 3
1573 1 1
1583 3 3
1594 4 5
160
161*/
原题是 LG-P1768 天路。
赛时写了个
xxxxxxxxxx
1461
2
3
4
5
6/******************************
7abbr
8
9******************************/
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15
16typedef unsigned int uint;
17typedef unsigned long long unll;
18typedef long long ll;
19
20template<typename T = int>
21inline T read(void);
22
23struct Node{
24 int v, p;
25 Node(int v, int p):v(v), p(p){;}
26 Node(void) = default;
27 bool operator < (const Node d)const{/////////////////////
28 if(!this->p || !this->v)return true;
29 if(!d.p || !d.v)return false;
30 double x = (double)this->v / (double)this->p;
31 double y = (double)d.v / (double)d.p;
32 return x < y;
33 }
34 bool operator > (const Node d)const{/////////////////////
35 if(!this->p || !this->v)return false;
36 if(!d.p || !d.v)return true;
37 double x = (double)this->v / (double)this->p;
38 double y = (double)d.v / (double)d.p;
39 return x > y;
40 }
41 Node operator + (Node d){
42 return Node(this->v + d.v, this->p + d.p);
43 }
44 void operator = (Node d){
45 this->p = d.p;
46 this->v =d.v;
47 }
48};
49
50struct Edge{
51 Edge* nxt;
52 int to;
53 Node val;
54 void* operator new(size_t);
55 Edge(Edge* nxt, int to, Node val):nxt(nxt), to(to), val(val){;}
56 Edge(void) = default;
57}eData[21000];
58void* Edge::operator new(size_t){static Edge* P = eData; return ++P;}
59Edge* head[7500];
60
61int N, M;
62
63bool vis[22];
64Node dis[22];
65void Dijk(int);
66
67
68
69priority_queue <
70 pair < Node, int >/*value, vertex*/,
71 vector < pair < Node, int > >,
72 less < pair < Node, int > >
73> vert;
74
75int main(){
76 freopen("road.in", "r", stdin);
77 freopen("road.out", "w", stdout);
78 N = read(), M = read();
79 for(int i = 1; i <= M; ++i){
80 int f = read(), t = read(), v = read(), p = read();
81 if(f == t)continue;
82 head[f] = new Edge(head[f], t, Node(v, p));
83 }
84 Node ans(0, 0);
85 for(int i = 1; i <= N; ++i){
86 Dijk(i);
87 if(dis[i] > ans)ans = dis[i];
88 // printf("No.%d %.3lf\n", i, (double)dis[i].v / (double)dis[i].p);
89 }
90 if(!ans.v || !ans.p)printf("-1\n");
91 else printf("%.1lf\n", (double)ans.v / (double)ans.p);
92
93 // fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
94 return 0;
95}
96
97
98void Dijk(int S){
99 memset(vis, false, sizeof(vis));
100 // memset(dis, 0x3f, sizeof(dis));
101 for(int i = 1; i <= N; ++i)dis[i].v = 0, dis[i].p = 0x3f3f3f3f;
102 dis[S] = Node(0, 0);
103 vert.push(make_pair(dis[S], S));
104 while(!vert.empty()){
105 int p;
106 tie(ignore, p) = vert.top();
107 vert.pop();
108 if(vis[p])continue;
109 vis[p] = true;
110 if(p == S)vis[p] = false;
111 for(auto i = head[p]; i; i = i->nxt){
112 if(dis[p] + i->val > dis[i->to]){
113 dis[i->to] = dis[p] + i->val;
114 if(!vis[i->to])vert.push(make_pair(dis[i->to], i->to));
115 }
116 }
117 }
118}
119
120template<typename T>
121inline T read(void){
122 T ret(0);
123 short flag(1);
124 char c = getchar();
125 while(c != '-' && !isdigit(c))c = getchar();
126 if(c == '-')flag = -1, c = getchar();
127 while(isdigit(c)){
128 ret *= 10;
129 ret += int(c - '0');
130 c = getchar();
131 }
132 ret *= flag;
133 return ret;
134}
135
136/*
137
1385 6
1391 2 1 1
1404 1 6 2
1415 4 8 1
1422 3 2 2
1435 2 4 1
1443 5 6 4
145
146*/
差为 1 即可全部覆盖的性质找到了,但是裴蜀定理不太熟悉,没给它转化为 gcd 为 1,所以最后只能打了个暴力。
xxxxxxxxxx
801
2
3
4
5
6
7
8/******************************
9abbr
10
11******************************/
12
13using namespace std;
14
15mt19937 rnd(random_device{}());
16int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21
22
23
24template<typename T = int>
25inline T read(void);
26
27int N;
28int len[310], pri[310];
29ll ans(LLONG_MAX);
30void bfs(){
31 queue < pair < int, int > >q;
32 q.push(make_pair(0, 0));
33 while(!q.empty()){
34 int cur, cpri;
35 tie(cur, cpri) = q.front();
36 q.pop();
37 if(cur == 1){
38 ans = min(ans, cpri);
39 }
40 for(int i = 1; i <= N; ++i){
41 q.push(make_pair(cur + len[i], cpri + pri[i]));
42 q.push(make_pair(cur - len[i], cpri + pri[i]));
43 }
44 if((double)clock() / CLOCKS_PER_SEC > 1.8){
45 if(ans == LLONG_MAX)printf("-1\n");
46 else printf("%lld\n", ans);
47 exit(0);
48 }
49 }
50}
51signed main(){
52 freopen("jump.in", "r", stdin);
53 freopen("jump.out", "w", stdout);
54 N = read();
55 for(int i = 1; i <= N; ++i)len[i] = read();
56 for(int i = 1; i <= N; ++i)pri[i] = read();
57 // int dep(0);
58 bfs();
59 // printf("%lld\n", ans);
60 // fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
61 return 0;
62}
63
64
65
66template<typename T>
67inline T read(void){
68 T ret(0);
69 short flag(1);
70 char c = getchar();
71 while(c != '-' && !isdigit(c))c = getchar();
72 if(c == '-')flag = -1, c = getchar();
73 while(isdigit(c)){
74 ret *= 10;
75 ret += int(c - '0');
76 c = getchar();
77 }
78 ret *= flag;
79 return ret;
80}
我不会
还挺显然的,简单改了一下没过,咕咕咕
大概是二分答案然后 SPFA 找环,emmmm,这个找时间再弄一下,SPFA 没怎么写过,暂时先咕掉。
正解是状压 DP,因为质因数最多好像就八个。不过这道题可以用 map 优化直接切掉,并且复杂度似乎还是正确的。。。
拆点 + 费用流,挺难我不会,还得再看看费用流。
update-2022_09_13 初稿