题解

75 条题解

  • 9
    @ 2015-11-24 14:29:24

    首先floyd求点对距离,然后枚举路径的起点与终点点i和j,若dist[i][j] < s 则继续:枚举图中所有点,求出这些点到路径 i->j 距离的最大值 t。ECC = MIN(ECC, t)
    那么怎么求树中 节点k 到 路径i->j 的距离呢?由于树结构的特殊性,我们易得

    distance = (dist[k][i]+dist[k][j]-dist[i][j]) / 2

    这条式子实质上就是把重复的路径减掉。可以画图验证。

  • 4
    @ 2017-10-20 23:41:45

    参考了@wang_yanheng的思路
    其实不用找直径,因为最优解一定在直径上,所以题中的限制条件就不用管了,多条直径找着麻烦,不如枚举,取最小即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #define LL long long 
    using namespace std;
    template <class _T> inline void read(_T &_x) {
        int _t; bool _flag=false;
        while((_t=getchar())!='-'&&(_t<'0'||_t>'9')) ;
        if(_t=='-') _flag=true,_t=getchar(); _x=_t-'0';
        while((_t=getchar())>='0'&&_t<='9') _x=_x*10+_t-'0';
        if(_flag) _x=-_x;
    }
    const int maxn=305;
    const int inf=0x3f3f3f3f;
    int n,s,x,y,z,dis[maxn][maxn],ans=inf;
    int main(){
        memset(dis,63,sizeof dis);
        read(n);read(s);
        for(int i=1;i<n;i++){
            read(x),read(y),read(z);
            dis[x][y]=dis[y][x]=z;
        }
        for(int k=1;k<=n;++k)
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
        int t;
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                dis[i][i]=0;
                if(dis[i][j]>s)continue;
                t=0;
                for(int k=1;k<=n;++k){
                    t=max(t,(dis[k][i]+dis[k][j]-dis[i][j])/2);
                }
                ans=min(ans,t);
            }
        }
        printf("%d",ans);
        return 0;
    }
    
    • @ 2018-06-05 20:32:53

      请问为什么点k到线段i,j的距离不是min(dist[k][i],dist[k][j])而是(dist[k][i]+dist[k][j]-dist[i][j])/2呢?

  • 2
    @ 2018-04-03 14:31:17

    这题思路很明确。注意到这题规模只有300,不如略带暴力地查找。
    首先用Floyd算法预处理点对之间的距离,接下来穷举每一对点构成的路径(假装每一条路径就是树网的核),如果路径长<=s,则计算其它点到该路径的最大距离,取穷举到的所有路径中最小的那个,即为答案。此时,对应的路径是最优解,也必然是树网的核。
    注意树网的核可能退化为一个点,因此在穷举点对(i,j)时不要忽略i==j的情况。
    至于点到路径的距离,之前的julao已经讲得很好了,像我这种蒟蒻只能借鉴一下啦。
    下面贴上代码。

    #include <bits/stdc++.h>
    #define F(i) for(int i=1; i<=n; ++i)            //运用宏简化代码
    
    const int N=305,INF=0x3f3f3f3f;
    int n,s,l,y,x,ans=INF,g[N][N];
    
    inline void read(int &x){                       //输入优化
        char c;                                     //虽然本题数据规模
        while(!isdigit(c=getchar())); x=c-48;       //不需要输入优化
        while(isdigit(c=getchar()))x=x*10+c-48;
    }
    
    inline int _min(int x,int y){return x<y?x:y;}
    inline int _max(int x,int y){return x>y?x:y;}
    
    int main(){
        read(n),read(s);
        memset(g,INF,sizeof g);                     //距离初值设为INF
        for(int i=1; i<n; ++i)                      //存图
            read(x),read(y),read(l),
            g[x][y]=g[y][x]=l;
        F(k) F(i) if(i!=k) F(j) if(i!=j && j!=k)    //标准的Floyd算法
            g[i][j]=_min(g[i][j],g[i][k]+g[k][j]);  //求点对间最短距离
        F(i) F(j) if(i==j || g[i][j]<=s){           //穷举路径i->j
            g[i][i]=0;                              //需要注意的是树的
            int dist=0;                             //核可能退化成一点
            F(k) if(k!=i && k!=j)                   //查找偏心距
                dist=_max(dist,(g[k][i]+g[k][j]-g[i][j])/2);
            ans=_min(ans,dist);                     //更新最小值
        }
        printf("%d\n",ans);
    }
    
  • 0
    @ 2016-08-29 19:44:10

    O(n)算法....
    ```pascal
    program vjiosP1362;

    type
    point=^node;
    node=record
    data,w:longint;
    next:point;
    end;
    var
    n,s:longint;
    head:array[1..300] of point;
    list:array[1..300] of longint;
    lists:longint;
    visit,flag:array[1..300] of boolean;
    pre,pred,sum,f:array[1..300] of longint;
    key,max:longint;
    ans:longint;
    queue,qt:array[1..300] of longint;
    qhead,qtail:longint;

    function maxf(a,b:longint):longint;
    begin
    if a>b then
    exit(a)
    else
    exit(b);
    end;

    function minf(a,b:longint):longint;
    begin
    if a<b then
    exit(a)
    else
    exit(b);
    end;

    procedure initdfs;
    begin
    fillchar(visit,sizeof(visit),0);
    fillchar(pre,sizeof(pre),0);
    fillchar(pred,sizeof(pred),0);
    max:=0;
    end;

    procedure initq;
    begin
    qhead:=1;
    qtail:=1;
    end;

    procedure put(data,id:longint);
    var
    tmp:longint;
    begin
    tmp:=qhead;
    while queue[tmp]>data do
    inc(tmp);
    queue[tmp]:=data;
    qt[tmp]:=id;
    qtail:=tmp;
    end;

    function find(l:longint):longint;
    begin
    while qt[qhead]<l do inc(qhead);
    exit(queue[qhead]);
    end;

    procedure initp(x:longint);
    begin
    head[x]:=nil;
    end;

    procedure insert(u,v,w:longint);
    var
    p:point;
    begin
    new(p);
    p^.data:=v;
    p^.w:=w;
    p^.next:=head[u];
    head[u]:=p;
    end;

    procedure inputdata;
    var
    i:longint;
    u,v,w:longint;
    begin
    fillchar(flag,sizeof(flag),false);
    readln(n,s);
    for i:=1 to n do
    initp(i);
    for i:=1 to n-1 do
    begin
    readln(u,v,w);
    insert(u,v,w);
    insert(v,u,w);
    end;
    end;

    procedure dfs(id,dist:longint);
    var
    now:point;
    nowid,nowd:longint;
    begin
    visit[id]:=true;
    now:=head[id];
    while now<>nil do
    begin
    nowid:=now^.data;
    nowd:=dist+now^.w;
    if (not visit[nowid]) and (not flag[nowid]) then
    begin
    pre[nowid]:=id;
    pred[nowid]:=now^.w;
    if nowd>max then
    begin
    key:=nowid;
    max:=nowd;
    end;
    dfs(nowid,nowd);
    end;
    now:=now^.next;
    end;
    end;

    procedure work1;
    var
    now,t:longint;
    i:longint;
    begin
    initdfs;
    pre[1]:=1;
    dfs(1,0);
    initdfs;
    pre[key]:=key;
    pred[key]:=0;
    dfs(key,0);

    fillchar(sum,sizeof(sum),0);
    lists:=1;
    list[1]:=key;
    t:=pred[key];
    now:=pre[key];
    while pre[now]<>now do
    begin
    inc(lists);
    list[lists]:=now;
    sum[lists]:=sum[lists-1]+t;
    t:=pred[now];
    now:=pre[now];
    end;
    inc(lists);
    list[lists]:=now;
    sum[lists]:=sum[lists-1]+t;
    for i:=1 to lists do
    flag[list[i]]:=true;
    end;

    procedure work2;
    var
    i:longint;
    begin
    for i:=1 to lists do
    begin
    initdfs;
    dfs(list[i],0);
    f[i]:=max;
    end;
    end;

    procedure work3;
    var
    tl,tr:longint;
    tot,tmp:longint;
    begin
    ans:=200000000; initq;
    tl:=1; tr:=1; put(f[1],1);
    repeat
    while (sum[tr+1]-sum[tl]<=s) and (tr<lists) do
    begin
    inc(tr);
    put(f[tr],tr);
    end;
    tot:=0;
    tot:=maxf(sum[tl],find(tl));
    tot:=maxf(tot,sum[lists]-sum[tr]);
    ans:=minf(ans,tot);

    inc(tl);
    if tr>=lists then break;
    until tr=lists;
    end;

    begin
    inputdata;
    work1;
    work2;
    work3;
    writeln(ans);
    end.
    ```

  • 0
    @ 2016-07-25 12:15:06

    楼下所言极是,给出一个O(n^2*d+n*d^2)的实现【d为直径上所有点的总数】
    ``` c++
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;

    struct p {
    int to, next, dis;
    }edge[705];
    int head[305], top = 0;
    int dis[305][305];
    int ind[305], id = 0;
    bool been[305];
    int n, s;

    void push(int from, int to, int dis)
    {
    edge[++top].to = to;
    edge[top].dis = dis;
    edge[top].next = head[from];
    head[from] = top;
    }

    void deal(int from, int to)
    {
    if (!been[from]) {
    been[from] = 1;
    ind[++id] = from;
    }
    if(from != to){
    for (int i = head[from]; i; i = edge[i].next) {
    int nd = edge[i].to, length = edge[i].dis;
    if (dis[from][to] == dis[nd][to]+length)
    deal(nd, to);
    }
    }
    }

    int main()
    {
    memset(head,0,sizeof head);
    memset(dis, 127/3, sizeof dis);
    scanf("%d%d", &n, &s);
    for (int i = 1; i < n; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    push(a, b, c);
    push(b, a, c);
    been[i] = 0;
    dis[i][i] = 0;
    }
    dis[n][n] = 0;
    been[n] = 0;
    int d = 0;
    for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
    for (int ji = head[k]; ji; ji = edge[ji].next) {
    int j = edge[ji].to, length = edge[ji].dis;
    dis[i][j] = dis[j][i] = min(dis[i][j], dis[i][k]+length);
    if (dis[i][j] <= 100000000)
    d = max(d, dis[i][j]);
    }
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
    if (dis[i][j] == d)
    deal(i, j);
    int ecc = 100000000;
    for (int i = 1; i <= id; i++)
    for (int j = 1; j <= id; j++) {
    int ni = ind[i], nj = ind[j], ans = 0;
    if (dis[ni][nj] <= s) {
    for (int k = 1; k <= n; k++) {
    ans = max(ans, (dis[k][ni]+dis[k][nj]-dis[ni][nj])>>1);
    // cout << ans << endl;
    }
    ecc = min(ecc, ans);
    }
    }
    cout << ecc <<endl;
    return 0;
    }

    事实上是可以压缩到T(n) = n^2+n-1+n^2+nd^2 = O(n^2+nd^2)的。不过这弱数据就算了。。
    
  • 0
    @ 2015-09-10 20:46:32

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #define M 1000000000
    using namespace std;
    const int MAXN = 310;

    int n, mlong, f[MAXN][MAXN];
    bool use[MAXN][MAXN];

    void Floyd(){
    for(int k=1; k<=n; k++)
    for(int i=1; i<=n; i++)
    for(int j=1; j<=n; j++)
    if(k != i && k!= j && i != j)
    f[i][j] = min(f[i][j], f[i][k] + f[k][j]);//maybe there is no way, so use min
    }

    int main()
    {
    int x, y, l, lim, ans = M;
    scanf("%d%d", &n, &lim);
    for(int i=1; i<=n; i++)
    for(int j=1; j<=n; j++)
    f[i][j] = M;
    for(int i=1; i<n; i++){
    scanf("%d%d%d", &x, &y, &l);
    f[x][y] = f[y][x] = l;
    }
    for(int i=1; i<=n; i++)
    f[i][i] = 0;
    Floyd();

    for(int i=1; i<=n; i++)
    for(int j=1; j<=n; j++)
    mlong = max(mlong, f[i][j]);
    for(int i=1; i<=n; i++)
    for(int j=1; j<=n; j++)
    if(f[i][j] == mlong && !use[i][j] && !use[j][i]){
    for(int k=1; k<=n; k++)
    if(f[i][k] + f[k][j] == mlong)
    for(int l=1; l<=n; l++)
    if(f[i][l] + f[l][j] == mlong && f[k][l] <= lim)
    ans = min(ans, max(min(f[k][i], f[l][i]), min(f[j][k], f[j][l])));
    use[i][j] = true;
    }
    printf("%d", ans);

    return 0;
    }
    Floyd + 暴力 , 有点复杂...

  • 0
    @ 2015-07-04 17:12:29

    先找出直径,枚举直径上每一段(包括点)即可。注意:如果点i到直径上点j有路径且路径不经过直径上其他点,才ok。

    #include<stdio.h>
    #define MAXVALUE 100000000
    int map[301][301];
    int path[301][301];
    int bools[301]={0};
    int ansbool[301]={0};
    int value[301];
    int ans=MAXVALUE,mid=-1;
    int n,s;

    int min(int a,int b)
    {
    if(a<b) return a;
    else return b;
    }

    int max(int a,int b)
    {
    if(a>b) return a;
    else return b;
    }

    void getd(int a,int b)
    {
    bools[a]=1;
    bools[b]=1;

    if(path[a][b]!=0 && path[a][b]!=-1) {getd(a,path[a][b]);getd(path[a][b],b);}
    }

    void getbool(int a,int b)
    {
    ansbool[a]=1;
    ansbool[b]=1;

    if(path[a][b]!=0 && path[a][b]!=-1) {getbool(a,path[a][b]);getbool(path[a][b],b);}
    }

    void getans1(int a)
    {
    int i,x=-1;

    for(i=1;i<=n;i++)
    if(map[a][i]!=MAXVALUE) x=max(x,map[a][i]);

    if(x!=-1) ans=min(ans,x);
    }

    void getans2(int a)
    {
    int i;

    for(i=1;i<=n;i++)
    {
    if(map[a][i]!=MAXVALUE)

    value[i]=min(value[i],map[a][i]);

    }
    }

    int main( )
    {

    int i,j,k,x1,x2,v,maxn=-1,dis=-1;

    scanf("%d %d",&n,&s);

    for(i=0;i<=300;i++)
    for(j=0;j<=300;j++)
    {
    map[i][j]=MAXVALUE;

    if(i==j) path[i][j]=0;
    else path[i][j]=-1;

    }

    for(i=1;i<=n;i++)
    {
    scanf("%d %d %d",&x1,&x2,&v);
    map[x1][x2]=v;
    map[x2][x1]=v;
    path[x1][x2]=0;
    path[x2][x1]=0;
    }

    for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
    if(i!=j)
    {
    map[i][j]=min(map[i][j],map[i][k]+map[k][j]);

    if(map[i][j]==map[i][k]+map[k][j]) path[i][j]=k;

    if(map[i][j]!=MAXVALUE) maxn=max(maxn,map[i][j]);
    }
    }

    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    if(map[i][j]==maxn) getd(i,j);

    for(i=1;i<=n;i++)
    if(bools[i]==1) getans1(i);

    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
    dis=-1;

    for(k=1;k<=n;k++)
    value[k]=MAXVALUE;

    if(map[i][j]!=MAXVALUE && map[i][j]<=s && bools[i]==1 && bools[j]==1) getbool(i,j);

    for(k=1;k<=n;k++)
    if(ansbool[k]==1) getans2(k);

    for(k=1;k<=n;k++)
    if(ansbool[k]==0) dis=max(dis,value[k]);

    ans=min(ans,dis);

    memset(ansbool,0,sizeof(ansbool));
    }

    printf("%d",ans);

    return 0;
    }

    • @ 2015-07-04 17:16:46

      点i到直径上点j有路径且路径不经过直径上其他点
      判断方法是:i到直径上所有点的距离中,到j的最小

      时间复杂度比较高

  • 0
    @ 2014-11-04 22:30:07

    鉴于下面只有一个人发了C++代码,但是有点丑(对不住了),我从发一个,跟下面那个C++的思想一致
    Floyd+爆搜

    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 888 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 888 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 884 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 888 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 884 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 888 KiB, score = 10
    测试数据 #6: Accepted, time = 500 ms, mem = 884 KiB, score = 10
    测试数据 #7: Accepted, time = 437 ms, mem = 884 KiB, score = 10
    测试数据 #8: Accepted, time = 78 ms, mem = 888 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 888 KiB, score = 10
    Accepted, time = 1015 ms, mem = 888 KiB, score = 100

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxn=301;
    const int inf=10000000;
    int map[maxn][maxn],f[maxn];
    int n,s;
    int ans=inf;
    int main()
    {
    scanf("%d %d",&n,&s);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    if(i!=j) map[i][j]=inf; else map[i][j]=0;
    for(int i=1;i<=n-1;i++)
    {
    int x,y,w; scanf("%d %d %d",&x,&y,&w);
    map[x][y]=w; map[y][x]=w;
    }
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    if(map[i][j]<=s)
    {
    for(int k=1;k<=n;k++)
    if(k!=i && k!=j) f[k]=inf; else f[k]=0;
    for(int k=1;k<=n;k++)
    if(map[i][k]+map[k][j]==map[i][j])
    {
    f[k]=0;
    for(int g=1;g<=n;g++)
    if(map[g][k]<f[g]) f[g]=map[g][k];
    }
    int dis=-1; bool tle=true;
    for(int k=1;k<=n;k++)
    if(f[k]>ans)
    {tle=false; break;}
    else
    dis=max(dis,f[k]);
    if(tle) ans=min(ans,dis);
    }
    printf("%d",ans);
    return 0;
    }

  • 0
    @ 2014-10-27 19:58:13

    1小时AC

    爽啊!

    var x,y,l,i,j,k,m,n,p,q,t,s,max,head,tail:longint;
    a:array[0..300,0..300] of longint;
    vetex,dist:array[0..300,0..300] of longint;
    pre,way:array[0..300] of longint;
    ans:longint;
    v:array[0..300] of boolean;
    ok:boolean;
    procedure findway(a:longint);
    var i,j:longint;
    begin
    if ok then exit;
    if a=tail then begin ok:=true; exit; end;
    for i:=1 to vetex[a,vetex[a,0]] do
    if not v[vetex[a,i]] then
    begin
    v[vetex[a,i]]:=true;
    pre[vetex[a,i]]:=a;
    findway(vetex[a,i]);
    end;
    end;
    procedure ecc(h,t:longint);
    var i,j:longint;
    tem,sum:longint;
    begin
    sum:=0;
    for j:=1 to n do
    begin
    tem:=1000000;
    for i:=h to t do
    begin
    if (dist[way[i],j]<tem) and (dist[way[i],j]<1000000) then
    tem:=dist[way[i],j];
    end;
    if sum<tem then sum:=tem;
    end;
    if sum<ans then ans:=sum;
    end;
    procedure floyed;
    begin
    for k:=1 to n do
    for i:=1 to n do
    for j:=1 to n do
    if (i<>j) and (i<>k) and (j<>k) and (dist[i,k]+dist[k,j]<dist[i,j]) then
    begin
    dist[i,j]:=dist[i,k]+dist[k,j];
    end;

    end;
    procedure work;
    begin
    for i:=1 to p do
    for j:=i to p do
    if (dist[way[i],way[j]]<=s) and (dist[way[i],way[j]]<1000000) then
    ecc(i,j);
    end;
    begin
    ans:=10000000;
    read(n,s);
    for i:=1 to n do
    for j:=1 to n do
    dist[i,j]:=1000000;
    for i:=1 to n do
    dist[i,i]:=0;
    for i:=1 to n-1 do
    begin
    read(x,y,l);
    dist[x,y]:=l;
    dist[y,x]:=l;
    inc(vetex[x,0]);
    vetex[x,vetex[x,0]]:=y;
    inc(vetex[y,0]);
    vetex[y,vetex[y,0]]:=x;
    end;
    floyed;
    for i:=1 to n do
    for j:=i+1 to n do
    if (dist[i,j]>max) and (dist[i,j]<100000) then
    begin
    max:=dist[i,j];
    head:=i;
    tail:=j;
    end;
    findway(head);
    pre[head]:=0;
    k:=tail;
    repeat
    inc(p);
    way[p]:=k;
    k:=pre[k];
    until k=0;
    work;
    writeln(ans);
    end.

  • 0
    @ 2014-10-03 22:32:02

    program p1362;
    var
    a,b,f:array[1..300,1..300]of longint;
    o,l,r,i,j,k,t,n,s,x,y,z,ans,ansk,ansj:longint;
    d:array[1..300]of boolean;
    c:array[1..300]of longint;
    function fa(x,y,z:longint):boolean;
    var i:longint;
    begin
    for i:=x to y do if c[i]=z then exit(true);
    exit(false);
    end;
    procedure zhao(x,y:longint);
    begin
    if b[x,y]>0 then begin if b[x,b[x,y]]>0 then zhao(x,b[x,y]);
    inc(o);c[o]:=b[x,y];d[b[x,y]]:=true;
    if b[b[x,y],y]>0 then zhao(b[x,y],y);end;
    end;
    begin
    ans:=0;
    readln(n,s);for i:=1 to n do for j:=1 to n do a[i,j]:=100000000;
    for i:=1 to n do a[i,i]:=0;
    for i:=1 to n-1 do begin read(x,y,z);a[x,y]:=z;a[y,x]:=z;end;f:=a;
    for k:=1 to n do for i:=1 to n do for j:=1 to n do
    if f[i,k]+f[k,j]<f[i,j] then begin f[i,j]:=f[i,k]+f[k,j];
    b[i,j]:=k;end;
    for i:=1 to n do for j:=1 to n do
    if f[i,j]>ans then begin ans:=f[i,j];l:=i;r:=j;end;
    o:=1;c[1]:=l;d[l]:=true;zhao(l,r);inc(o);c[o]:=r;d[r]:=true;
    ans:=maxlongint;
    for i:=1 to o do begin ansj:=maxlongint;
    for j:=i to o do if f[c[i],c[j]]>s then continue else begin
    ansj:=maxlongint;ansk:=0;
    for k:=1 to n do begin
    t:=maxlongint;
    for l:=i to j do if (f[c[l],k]<t)and not fa(i,j,k) then t:=f[c[l],k];
    if t=maxlongint then t:=0;//if t=9 then write(i,j,c[i],c[j],k,' ');
    if t>ansk then ansk:=t;end;
    if ansk<ansj then ansj:=ansk;end;if ansj<ans then ans:=ansj;end;
    writeln(ans);
    end.
    可以说是n^5了

  • 0
    @ 2013-11-04 16:21:54

    我用超暴力的 O(n^5) 算法居然都能过,这数据太水

  • 0
    @ 2013-10-21 20:19:24

    O(n)整个直径上所有点的序列
    然后枚举直径上每一段,并使之尽可能长,
    然后O(n)DFS求偏心距,维护最小值
    时间复杂度O(n^2)

  • 0
    @ 2012-10-22 21:27:57

    浓缩就是精华

    #include

    #include

    using namespace std;

    int a[301][301],f[301];int main(){int n,s,min=1000000;cin >>n >>s;for (int k=1;k>y >>z;a[x][y]=z;a[y][x]=z;}for (int k=1;k

  • 0
    @ 2012-07-29 12:10:28

    编译通过... 

    ├ 测试数据 01:答案正确... 0ms 

    ├ 测试数据 02:答案正确... 0ms 

    ├ 测试数据 03:答案正确... 0ms 

    ├ 测试数据 04:答案正确... 0ms 

    ├ 测试数据 05:答案正确... 0ms 

    ├ 测试数据 06:答案正确... 0ms 

    ├ 测试数据 07:答案正确... 41ms 

    ├ 测试数据 08:答案正确... 56ms 

    ├ 测试数据 09:答案正确... 0ms 

    ├ 测试数据 10:答案正确... 0ms 

    ---|---|---|---|---|---|---|---|- 

    Accepted 有效得分:100 有效耗时:97ms 

    floyd+暴力枚举

    话说看题看了一个小时

  • 0
    @ 2010-03-16 22:54:49

    话说最讨厌看文字题、术语特多题……

  • 0
    @ 2009-11-14 09:33:45

    加强版的出bug了,先在这里试一下。发现秒杀了。

  • 0
    @ 2009-11-11 16:48:05

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    好像还蛮容易的说,,

    大家加油,不要害怕~~

  • 0
    @ 2009-11-09 11:57:32

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    对于每个点用F记录他每个分支路径所能形成的最大值。

    完成后顺带找出直径。

    枚举直径上的每段S。得解

  • 0
    @ 2009-11-07 11:56:54

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 103ms

    ├ 测试数据 08:答案正确... 166ms

    ├ 测试数据 09:答案正确... 166ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:435ms

    小小改动:

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 41ms

    ├ 测试数据 08:答案正确... 56ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    再一改(纯属想象):

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

  • 0
    @ 2009-11-07 08:13:32

    过程流

    纪念提交第100道题

    AC的第50道

    难度为3

    太高兴啦!

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 103ms

    ├ 测试数据 08:答案正确... 150ms

    ├ 测试数据 09:答案正确... 134ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:387ms

    type

    integer=longint;

    var

    x,y,m,max,min,ma,fa,a,b,c,i,j,k,l,n,t,s,o:integer;

    g,d,v,next,ks,e:array[1..600]of integer;

    p,f:array[1..300,1..300]of int64;

    procedure int;

    begin

    readln(n,s);

    for i:=1 to n do for j:=1 to n do f:=maxlongint;

    for i:=1 to n-1 do

    begin

    readln(a,b,c);

    inc(t);next[t]:=ks[a];ks[a]:=t;e[t]:=b;g[t]:=c;

    inc(t);next[t]:=ks;ks:=t;e[t]:=a;g[t]:=c;

    f[a,b]:=c;f:=c;

    end;

    end;

    procedure floyed;

    var

    i,j,k:integer;

    begin

    for k:=1 to n do

    for i:=1 to n do

    if ki then

    for j:=1 to n do

    if(jk)and(ji)then

    if f+f[k,j]max then begin max:=m;fa:=i;end;

    end;

    procedure dfs1(i,j:integer);

    begin

    if p=0then begin inc(o);d[o]:=j;end

    else

    begin

    dfs1(i,p);dfs1(p,j);

    end;

    end;

    procedure meiju;

    var a,b:array[1..300]of integer;

    begin

    min:=maxlongint;

    for i:=1 to o do

    for j:=i to o do

    begin

    if(f[d[i],d[j]]

信息

ID
1362
难度
5
分类
树结构 点击显示
标签
递交数
1905
已通过
697
通过率
37%
被复制
10
上传者