• loj刷题记录2019/2/20


    #10064. 「一本通 3.1 例 1」黑暗城堡

    题目描述

    你知道黑暗城堡有 NNN 个房间,MMM 条可以制造的双向通道,以及每条通道的长度。

    城堡是树形的并且满足下面的条件:

    DiD_iDi 为如果所有的通道都被修建,第 iii 号房间与第 111 号房间的最短路径长度;

    SiS_iSi 为实际修建的树形城堡中第 iii 号房间与第 111 号房间的路径长度;

    要求对于所有整数 iii (1≤i≤N1le ile N1iN),有 Si=DiS_i= D_iSi=Di 成立。

    你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对 231−12^{31} -12311 取模之后的结果就行了。

    输入格式

    第一行为两个由空格隔开的整数 N,MN, MN,M;

    第二行到第 M+1M+1M+1 行为 333 个由空格隔开的整数 x,y,lx, y, lx,y,l:表示 xxx 号房间与 yyy 号房间之间的通道长度为 lll。

    输出格式

    一个整数:不同的城堡修建方案数对 231−12^{31} -12311 取模之后的结果。

    样例

    样例输入

    4 6
    1 2 1
    1 3 2
    1 4 3
    2 3 1
    2 4 2
    3 4 1

    样例输出

    6

    样例说明

    一共有 444 个房间,666 条道路,其中 111 号和 222 号,111 号和 333 号,111 号和 444 号,222 号和 333 号,222 号和 444 号,333 号和 444 号房间之间的通道长度分别为 111,222,333,111,222,111。

    而不同的城堡修建方案数对 231−12^{31} -12311 取模之后的结果为 666。

    先跑一次最短路,再将每一个点的方案数算出来,根据乘法远离相乘

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const long long mod = (1 << 31) - 1;
     4 const int maxn = 1010;
     5 const int maxm = 1e6;
     6 int n, m, head[maxn], size, mp[maxn][maxn], dis[maxn];
     7 bool bj[maxn];
     8 long long ans = 1;
     9 struct edge {
    10     int v, nex, w;
    11 } e[maxm << 1];
    12 
    13 struct node {
    14     int pos, cost;
    15     node(int pos = 0, int cost = 0) : pos(pos), cost(cost) {}
    16     friend bool operator<(node a, node b) { return a.cost > b.cost; }
    17 };
    18 
    19 void adde(int u, int v, int w) {
    20     e[size].v = v;
    21     e[size].w = w;
    22     e[size].nex = head[u];
    23     head[u] = size++;
    24 }
    25 
    26 void spfa() {
    27     dis[1] = 0, bj[1] = 0;
    28     priority_queue<node> q;
    29     q.push(node(1, 0));
    30     while (!q.empty()) {
    31         node a = q.top();
    32         q.pop();
    33         bj[a.pos] = 0;
    34         int u = a.pos;
    35         for (int i = head[u]; ~i; i = e[i].nex) {
    36             int v = e[i].v, w = e[i].w;
    37             if (dis[v] > dis[u] + w) {
    38                 dis[v] = dis[u] + w;
    39                 if (!bj[v]) {
    40                     bj[v] = 1;
    41                     q.push(node(v, dis[v]));
    42                 }
    43             }
    44         }
    45     }
    46 }
    47 
    48 int main() {
    49     // freopen("in.txt","r",stdin);
    50     memset(head, -1, sizeof(head));
    51     memset(mp, 0x3f, sizeof(mp));
    52     memset(dis, 0x3f, sizeof(dis));
    53     scanf("%d%d", &n, &m);
    54     for (int i = 1; i <= m; i++) {
    55         int u, v, w;
    56         scanf("%d%d%d", &u, &v, &w);
    57         mp[u][v] = mp[v][u] = min(mp[u][v], w);
    58         adde(u, v, w);
    59         adde(v, u, w);
    60     }
    61     spfa();
    62     for (int i = 2; i <= n; i++) {
    63         long long cnt = 0;
    64         for (int j = 1; j <= n; j++) {
    65             if (mp[j][i] < 300 && dis[j] + mp[j][i] == dis[i])
    66                 cnt++;
    67         }
    68         ans = (ans * cnt) % mod;
    69         // printf("%d
    ",ans);
    70     }
    71     printf("%lld", ans);
    72     return 0;
    73 }
    View Code

    「一本通 3.1 例 2」北极通讯网络

    题目描述

    原题来自:Waterloo University 2002

    北极的某区域共有 nnn 座村庄,每座村庄的坐标用一对整数 (x,yx, yx,y) 表示。为了加强联系,决定在村庄之间建立通讯网络。通讯工具可以是无线电收发机,也可以是卫星设备。所有的村庄都可以拥有一部无线电收发机, 且所有的无线电收发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设备。

    不同型号的无线电收发机有一个不同的参数 ddd,两座村庄之间的距离如果不超过 ddd 就可以用该型号的无线电收发机直接通讯,ddd 值越大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直接通讯。

    现在有 kkk 台卫星设备,请你编一个程序,计算出应该如何分配这 kkk 台卫星设备,才能使所拥有的无线电收发机的 ddd 值最小,并保证每两座村庄之间都可以直接或间接地通讯。

    例如,对于下面三座村庄:

    Picture1

    其中 ∣AB∣=10,∣BC∣=20,∣AC∣=105≈22.36|AB|= 10, |BC|= 20, |AC|= 10sqrt{5}≈22.36AB=10,BC=20,AC=105

    22.36

    如果没有任何卫星设备或只有 111 台卫星设备 (k=0k=0k=0 或 k=1k=1k=1),则满足条件的最小的 d=20d = 20d=20,因为 AAA 和 BBB,BBB 和 CCC 可以用无线电直接通讯;而 AAA 和 CCC 可以用 BBB 中转实现间接通讯 (即消息从 AAA 传到 BBB,再从 BBB 传到 CCC);

    如果有 222 台卫星设备 (k=2k=2k=2),则可以把这两台设备分别分配给 BBB 和 CCC ,这样最小的 ddd 可取 101010,因为 AAA 和 BBB 之间可以用无线电直接通讯;BBB 和 CCC 之间可以用卫星直接通讯;AAA 和 CCC 可以用 BBB 中转实现间接通讯。

    如果有 333 台卫星设备,则 A,B,CA,B,CA,B,C 两两之间都可以直接用卫星通讯,最小的 ddd 可取 000。

    输入格式

    第一行为由空格隔开的两个整数 n,kn,kn,k;

    2∼n+12sim n+12n+1 行,每行两个整数,第 iii 行的 xi,yix_i,y_ixi,yi 表示第 iii 座村庄的坐标 (xi,yix_i, y_ixi,yi)。

    输出格式

    一个实数,表示最小的 ddd 值,结果保留 222 位小数。

    样例

    样例输入

    3 2
    10 10
    10 0
    30 0

    样例输出

    10.00

    数据范围与提示

    即求最小生成树第k长的边

    证明过程可参考  https://www.cnblogs.com/mxrmxr/p/9846958.html

    先将dis数组的值初始化成与第一个借点的距离,即默认第一个点已在生成树上,在进行加边操作

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=505;
     4 int dis[maxn],n,k,x[maxn],y[maxn];
     5 bool vis[maxn];
     6 int cc(int a,int b){
     7     return (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]);
     8 }
     9 bool cmp(int a,int b){
    10     return a>b;
    11 }
    12 int main(){
    13     scanf("%d%d",&n,&k);
    14     for(int i=1;i<=n;i++){
    15         scanf("%d%d",x+i,y+i);
    16         dis[i]=cc(1,i);
    17     }
    18     for(int i=1;i<n;i++){
    19         int minn=1e9,pos;
    20         for(int j=2;j<=n;j++) if(!vis[j]&&dis[j]<minn) minn=dis[pos=j];
    21         vis[pos]=1;
    22         for(int j=2;j<=n;j++) if(!vis[j]) dis[j]=min(dis[j],cc(j,pos));
    23     }
    24     sort(dis+1,dis+1+n,cmp);
    25     printf("%.2f",sqrt(dis[k]));
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    2019年11月4日随堂测试 最多输入字母统计
    写增删改查中间遇到的问题
    2019年12月9日下午自习成果
    2019年12月16日 分级考试
    2019年11月18日 JAVA期中考试 增删改查
    sql语言积累
    【转载】Java项目中常用的异常处理情况总结
    泛型
    C#数字格式化输出
    委托,Lambda的几种用法
  • 原文地址:https://www.cnblogs.com/plysc/p/10408311.html
Copyright © 2020-2023  润新知