题意:
给一个无向图,找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; }