|
发表于 2023-1-29 12:20:58
|
显示全部楼层
本楼为最佳答案
 感觉好像有点思路,试着写了一个
- #include <stdio.h>
- #include <stdint.h>
- #include <stdbool.h>
- const uint64_t mod = 1000000007;
- struct edge{
- int64_t weight;
- uint32_t destination;
- uint32_t next;
- };
- struct edge edges[(unsigned int)4e5];
- uint32_t head[(unsigned int)2e5 + 1];
- uint32_t next_edge;
- uint32_t n;
- int64_t l, r;
- void insert_edge(uint32_t source, uint32_t destination, int64_t weight){
- edges[next_edge].weight = weight;
- edges[next_edge].destination = destination;
- edges[next_edge].next = head[source];
- head[source] = next_edge++;
- }
- void trace(
- uint32_t target,
- int64_t p_weight, int64_t p_low, int64_t p_high,
- int64_t* c_low, int64_t* c_high
- ){
- uint32_t start = head[target];
- int64_t low = p_weight - p_high;
- int64_t high = p_weight - p_low;
- head[target] |= 1 << 31;
- int64_t child_low, child_high;
- for(uint32_t edge = start; edge != 0x7fffffff; edge = edges[edge].next){
- if(head[edges[edge].destination] >> 31 == 1) continue;
- if(edges[edge].weight - low < l || edges[edge].weight - high > r){
- low = 1;
- high = 0;
- break;
- }
- if(edges[edge].weight - r > low) low = edges[edge].weight - r;
- if(edges[edge].weight - l < high) high = edges[edge].weight - l;
- trace(edges[edge].destination, edges[edge].weight, low, high, &child_low, &child_high);
- if(child_low > child_high){
- low = 1;
- high = 0;
- break;
- }
- if(edges[edge].weight - child_high > low) low = edges[edge].weight - child_high;
- if(edges[edge].weight - child_low < high) high = edges[edge].weight - child_low;
- }
- *c_low = low;
- *c_high = high;
- }
- void group_main(){
- uint64_t result = 1;
- scanf("%u%ld%ld", &n, &l, &r);
- int64_t minimum_weight = l + l;
- int64_t maximum_weight = r + r;
- for(uint32_t i = 1; i <= n; i++) head[i] = 0x7fffffff;
- next_edge = 0;
- uint8_t op;
- uint32_t source, destination;
- int64_t weight;
- for(uint32_t i = 1; i < n; i++){
- scanf("%hhu", &op);
- if(op == 0) scanf("%*u%*u");
- else if(op == 1){
- scanf("%u%u%ld", &source, &destination, &weight);
- if(weight > maximum_weight || weight < minimum_weight){
- printf("0\n");
- return;
- }
- insert_edge(source, destination, weight);
- insert_edge(destination, source, weight);
- }
- }
- int64_t left, right;
- for(uint32_t i = 1; i <= n; i++){
- if(head[i] >> 31 == 0){
- trace(i, l + r, l, r, &left, &right);
- if(left > right){
- result = 0;
- break;
- }
- result = ((right - left + 1) * result) % mod;
- if(result == 0) break;
- }
- }
- printf("%lu\n", result);
- }
- int main(){
- uint8_t T;
- scanf("%hhu", &T);
- for(uint8_t i = 0; i < T; i++) group_main();
- return 0;
- }
复制代码 |
|