Telephone Lines USACO 月赛
2013-08-29 15:39
190 查看
以前做过这套题目
这个题又重新写了:/article/5825629.html
还是以前的思路
一直错在一个地方:决策的时候,如果没有走过,直接更新,如果走过,总是选最小值。如果走的是小于mid值的边,那么用tmp = max(dp[x][u] , e[i].val) 更新。
代码比以前好多了好像、
View Code
这个题又重新写了:/article/5825629.html
还是以前的思路
一直错在一个地方:决策的时候,如果没有走过,直接更新,如果走过,总是选最小值。如果走的是小于mid值的边,那么用tmp = max(dp[x][u] , e[i].val) 更新。
代码比以前好多了好像、
#define maxn 1005 int dp[maxn][maxn]; int n,m,k; struct node { int v,next; int val; int f; }; node e[10005 * 2 ]; int head[maxn]; int cnt ; void init() { cnt = 0 ; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { e[cnt].v = v ; e[cnt].val = w; e[cnt].next = head[u] ; head[u] = cnt ++ ; e[cnt].v = u ; e[cnt].val = w ; e[cnt].next = head[v]; head[v] = cnt ++ ; return ; } bool vis[maxn]; void dfs(int u) { vis[u]= 1 ; for(int i = head[u]; i != -1 ; i = e[i].next ) if(!vis[e[i].v] ) dfs(e[i].v); } queue< pair<int,int> > q; #define pii pair<int,int> bool vs[maxn][maxn]; void spfa() { pii cur,tt; int u , x; while(!q.empty()) q.pop(); dp[1][0] = 0 ; vs[1][0] = 1; q.push(make_pair(1,0)); while(!q.empty()) { cur = q.front(); q.pop(); u = cur.first; x = cur.second; for(int i = head[u]; i != -1 ; i = e[i].next ) { if(e[i].f == 1 ) { tt = make_pair(e[i].v , x + 1 ); if(x + 1 > k ) continue; // printf("%d %d %d %d\n",u,x,e[i].v,x+1); //int tmp = max(dp[e[i].v][x+1],dp[u][x]); if((dp[e[i].v][x+1] == -1 && dp[u][x] >= 0 )|| ( dp[e[i].v][x+1] != -1 && dp[u][x] >= 0 && dp[u][x] < dp[e[i].v][x+1] ) ) { dp[e[i].v][x+1] = dp[u][x] ; if(!vs[tt.first][tt.second]) { vs[tt.first][tt.second] = 1 ; q.push(tt); } } } else if(e[i].f == 0 ) { tt = make_pair(e[i].v,x); if(x > k ) continue; // printf("%d %d %d %d\n",u,x,e[i].v,x); int tmp = max(e[i].val , dp[u][x] ); if(dp[e[i].v][x] == -1 || tmp < dp[e[i].v][x]) { dp[e[i].v][x] = tmp; if(!vs[tt.first][tt.second]) { vs[tt.first][tt.second] = 1 ; q.push(tt); } } } } vs[u][x] = 0; } //if(dp [k] >= 0 ) puts("asjklsajk"); } int check() { memset(dp,-1,sizeof(dp)); memset(vs,0,sizeof(vs)); spfa(); //printf("dp [k] = %d\n",dp [k]); return dp [k]; } void build(int x) { for(int i = 1; i <= n ; i ++ ) { for(int j = head[i] ; j != -1 ; j = e[j].next) if(e[j].val > x ) e[j].f = 1; else e[j].f = 0 ; } } int _max; int main() { int u,v,w; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { init(); _max = 0 ; for(int i = 1 ; i <= m ; i ++ ) { scanf("%d%d%d",&u,&v,&w); _max = max(_max , w); add(u,v,w); } dfs(1); if(!vis ) { printf("-1\n"); continue; } int left , right ,mid ; left = 1 ; right = _max ; int ans ; int res; ans = 0x3f3f3f3f; while(left < right) { mid = (left + right ) / 2 ; //printf("mid = %d\n",mid); build(mid); res = check(); //printf("res = %d\n",res); if(res == -1 ) { // printf("%d\n",left); left = mid + 1 ; } else { ans = min(ans , res); right = mid ; } } printf("%d\n",ans); } return 0; } /* 8 10 2 1 2 1 1 3 10 2 3 2 3 4 11 3 5 3 4 5 10 4 8 12 4 6 9 5 7 4 6 7 5 */
View Code
相关文章推荐
- usaco 2008 January Telephone Lines 架设电话线 题解
- BZOJ [Usaco2007 Jan]Telephone Lines架设电话线(POJ 3662)
- [USACO08JAN]电话线Telephone Lines
- bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
- luogu P1948 [USACO08JAN]电话线Telephone Lines
- BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线 二分答案 最短路
- BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线【二分+spfa】
- bzoj1614【Usaco2007 Jan】Telephone Lines 架设电话线
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线(二分+SPFA)
- [Usaco2007 Jan]Telephone Lines架设电话线[二分答案+最短路思想]
- 二分查找+spfa(洛谷1948 [USACO08JAN]电话线Telephone Lines) 4000
- 洛谷 1948 [USACO08JAN]电话线Telephone Lines
- BZOJ1614 [Usaco2007 Jan]Telephone Lines架设电话线 二分/魔性剪枝/最小边长连通
- 【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
- (1614 [Usaco2007 Jan]Telephone Lines架设电话线)
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线 二分+最短路
- SPFA+二分-BZOJ-1614-[Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线