导航

题意:

给一个无向图,找1到n所有的路中每条路最小权值的最大值!

屌丝一开始的思想是利用dij的变形~

但是==屌丝忘记了更新dis数组~结果TLE无数次...

说正经的~dij的变形思想是这样的if(dis[now]<min(dis[pos],w[pos][now]))则更新dis[now]....这种变形的证明和原来dij的证明是一样的~大家自己脑补啊~

heap优化的dij用时250ms~

上代码~

恶心的是不知道邻接表要搞多少边~这里RE无数次==

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int min(int a,int b)
{
    if(a<b)
        return a;
    return b;
}
struct st
{
    int w,id;
    st(int a,int b){w=a;id=b;}
    st(){}
};
struct cmp
{
    bool operator()(const st &a,const st &b)
    {
        return a.w<b.w;
    }
};
int n,m;
const int inf=99999999;
int dis[1005];
struct edge
{
    int id,w;
    edge *next;
};
edge *adj[1005];
edge edges[100005];
int ednum;
inline void addEdge(int a,int b,int c)
{
    edge *aa;
    aa=&edges[ednum];
    ednum++;
    aa->id=b;
    aa->w=c;
    aa->next=adj[a];
    adj[a]=aa;
}
int solve()
{
    for(int i=1; i<=n; i++)
    {
        dis[i]=-1;
    }
    dis[1]=inf;
    st tmp;
    priority_queue<st,vector<st>,cmp>q;
    q.push(st(inf,1));
    while(!q.empty())
    {
        tmp=q.top();
        q.pop();
        if(tmp.id==n)
            return tmp.w;
        for(edge *p=adj[tmp.id];p;p=p->next)
        {
            if(dis[p->id]<min(dis[tmp.id],p->w))
            {
                dis[p->id]=min(dis[tmp.id],p->w);
                q.push(st(dis[p->id],p->id));
            }
        }
    }
}
int main()
{
    int t,a,b,c;
    scanf("%d",&t);
    for(int tt=1; tt<=t; tt++)
    {
        scanf("%d%d",&n,&m);
        ednum=0;
        for(int i=1; i<=n; i++)
            adj[i]=NULL;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addEdge(a,b,c);
            addEdge(b,a,c);
        }
        printf("Scenario #%d:\n%d\n",tt,solve());
        if(tt!=t)
            printf("\n");
    }
}

接下来是最大生成树的思想~

采用把边从大到小排序的思想,然后用并查集实现的方法~

每次加入边之后确认1和n的连通情况~当第一次实现两者连通之后就输出那条边的权值~

证明也是贪心的思想~大家自己脑补~

时间稍慢 344ms

上代码~

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=1999999999;
int n,m;
bool ok;
int rel;
int min(int a,int b)
{
    if(a<b)
        return a;
    return b;
}
struct edge
{
    int st,ed,w;
};
int me[1005];
edge edges[100005];
bool cmp(edge a,edge b)
{
    return a.w>b.w;
}
int findme(int a)
{
    if(a!=me[a])
        return me[a]=findme(me[a]);
    return a;
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int tt=1;tt<=t;tt++)
    {
        ok=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            me[i]=i;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&edges[i].st,&edges[i].ed,&edges[i].w);
        }
        sort(edges,edges+m,cmp);
        for(int i=0;i<m;i++)
        {
            int tmpa=findme(edges[i].st);
            int tmpb=findme(edges[i].ed);
            if(tmpa!=tmpb)
            {
                me[tmpb]=tmpa;
            }
            tmpa=findme(1);
            tmpb=findme(n);
            if(tmpa==tmpb)
            {
                rel=edges[i].w;
                break;
            }
        }
        printf("Scenario #%d:\n%d\n",tt,rel);
        if(tt!=t)
            printf("\n");
    }
    return 0;
}