HDU 1599 find the mincost route (无向图的最小环)
题意:
给一个带权无向图,求其至少有3个点组成的环的最小权之和。
思路:
(1)DFS可以做,实现了确实可以,只是TLE了。量少的时候应该还是可以水一下的。主要思路就是,深搜过程如果当前点搜到一个点访问过了,而其不是当前点的父亲,则肯定有环,可以更新答案。深搜过程要记录路径和,父亲,是否访问过等等信息,因为图可能有多个连通分量。
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
using namespace std;
const int N=;
struct node
{
int from, to, cost;
node(){};
node(int from,int to,int cost):from(from),to(to),cost(cost){};
}edge[N*N];
int edge_cnt;
vector<int> vect[N]; void add_node(int from,int to,int cost)
{
edge[edge_cnt]=node(from, to, cost);
vect[from].push_back(edge_cnt++);
} int sum[N], vis[N], inq[N], pre[N], ans; void DFS(int x)
{
vis[x]=;
inq[x]=;
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if( inq[e.to] && pre[x]!=e.to )
{
ans=min(ans, sum[x]+e.cost-sum[e.to]);
}
if( !inq[e.to] )
{
pre[e.to]=x;
sum[e.to]=sum[x]+e.cost;
DFS(e.to);
sum[e.to]=;
pre[e.to]=;
}
}
inq[x]=;
} int cal(int n)
{
ans=INF;
memset(vis,,sizeof(vis));
memset(inq,,sizeof(inq));
memset(pre,,sizeof(pre));
memset(sum,,sizeof(sum));
for(int i=; i<=n; i++)
{
if(!vis[i])
DFS(i);
}
return ans==INF? : ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b, c, n, m;
while(~scanf("%d %d", &n, &m))
{
edge_cnt=;
for(int i=; i<=n; i++) vect[i].clear(); for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
add_node(a, b, c);
add_node(b, a, c);
} int ans=cal(n);
if(ans) printf("%d\n", ans);
else printf("It's impossible.\n");
}
return ;
}
TLE代码
(2)dijkstra。枚举删除某一条边,求该边两点间的最短距离。要注意的是,重边只留1条权最小的,其他删掉,这样就能保证至少出现3个点。
608ms
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <deque>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
using namespace std;
const int N=;
struct node
{
int from, to, cost, tag;
node(){};
node(int from,int to,int cost):from(from),to(to),cost(cost),tag(){};
}edge[N*N];
int edge_cnt;
vector<int> vect[N];
int g[N][N];
void add_node(int from,int to,int cost)
{
edge[edge_cnt]=node(from, to, cost);
vect[from].push_back(edge_cnt++);
} int vis[N], cost[N];
int dijkstra(int s,int e)
{
memset(cost, 0x7f, sizeof(cost));
memset(vis, , sizeof(vis));
cost[s]=;
priority_queue<pii,vector<pii>,greater<pii> > que;
que.push(make_pair(, s)); while(!que.empty())
{
int x=que.top().second;
que.pop();
if(vis[x]) continue;
vis[x]=;
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if( e.tag && cost[e.to]>cost[x]+e.cost )
{
cost[e.to]=cost[x]+e.cost;
que.push(make_pair(cost[e.to], e.to));
}
}
}
return cost[e]; } int cal()
{
int ans=INF;
for(int i=; i<edge_cnt; i+=)
{
edge[i].tag=;
edge[i^].tag=;
ans=min(ans, edge[i].cost+dijkstra(edge[i].from, edge[i].to));
edge[i].tag=;
edge[i^].tag=;
}
return ans==INF? : ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b, c, n, m;
while(~scanf("%d %d", &n, &m))
{
edge_cnt=;
for(int i=; i<=n; i++) vect[i].clear();
memset(g, 0x7f, sizeof(g)); for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[b][a]=g[a][b]=min(g[a][b], c);
}
for(int i=; i<=n; i++) //为了去重边
{
for(int j=i+; j<=n; j++)
{
if(g[i][j]<INF)
{
add_node(i, j, g[i][j]);
add_node(j, i, g[i][j]);
}
}
}
int ans=cal();
if(ans) printf("%d\n", ans);
else printf("It's impossible.\n");
}
return ;
}
AC代码
(3)floyd。dijkstra是枚举删某条边,而floyd是枚举相连的两条边。先理解floyd的思想,穷举每个点k作为中间节点来更新其他点a和b之间的距离,而当某个点未被k枚举到时,是不可能有一条路径将其包含在中间的,它顶多可以作为路径的起点或者终点。利用这点,在未枚举到某点k作为中间点时,可以枚举一下与k相连的两条边,即i->k->j。
78ms
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
using namespace std;
const int N=;
int g[N][N], dist[N][N]; int cal(int n) //floyd
{
int ans=INF;
for(int k=; k<=n; k++) //注意枚举顺序。
{
//枚举两条边i->k->j。
for(int i=; i<=n; i++ )
{
if(g[i][k]==INF || k==i) continue;
for(int j=i+; j<=n; j++) //i和j不能相等,才能保证至少3个点。
{
if(g[k][j]==INF || dist[i][j]==INF || k==j ) continue;
int dis=g[i][k] + g[k][j] + dist[i][j];
ans=min(ans, dis);
}
}
for(int i=; i<=n; i++)
{
for(int j=; j<=n; j++)
{
if(dist[i][k]==INF || dist[k][j]==INF) continue;
dist[i][j]=min(dist[i][j], dist[i][k]+dist[k][j]);
}
}
} return ans==INF? : ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b, c, n, m;
while(~scanf("%d %d", &n, &m))
{
memset(g, 0x7f, sizeof(g));
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[b][a]=g[a][b]=min(g[a][b], c);
}
memcpy(dist, g, sizeof(g));
for(int i=; i<=n; i++) dist[i][i]=; int ans=cal(n);
if(ans) printf("%d\n", ans);
else printf("It's impossible.\n");
}
return ;
}
AC代码
HDU 1599 find the mincost route (无向图的最小环)的更多相关文章
- HDU 1599 find the mincost route(floyd求最小环 无向图)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1599 find the mincost route Time Limit: 1000/2000 MS ...
- hdu 1599 find the mincost route (最小环与floyd算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1599 find the mincost route Time Limit: 1000/2000 MS ...
- hdu 1599 find the mincost route(无向图的最小环)
find the mincost route Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- hdu 1599 find the mincost route floyd求无向图最小环
find the mincost route Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- hdu 1599 find the mincost route 最小环
题目链接:HDU - 1599 杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游路线,这个路线从A点出发并且最后回到A点,假设经过的路线为V1,V2,....VK,V1,那么必须 ...
- hdoj 1599 find the mincost route【floyd+最小环】
find the mincost route Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 1599 find the mincost route (无向图floyd最小环详解)
转载请注明出处:http://blog.csdn.net/a1dark 分析:终于弄懂了floyd的原理.以前的理解一直肤浅.所以一做到floyd应用的题.就拙计了.其实floyd的本质DP.利用前K ...
- hdu 1599 find the mincost route
http://acm.hdu.edu.cn/showproblem.php?pid=1599 floyd找最小环. #include <cstdio> #include <cstri ...
- hdu 1599 find the mincost route(flyod求最小环)
Problem Description 杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游路线,这个路线从A点出发并且最后回到A点,假设经过的路线为V1,V2,....VK,V1, ...
随机推荐
- sql server 存储过程,事务
1.存储过程,事务 CREATE PROCEDURE Proc_ceshi @id int, ), @returnval int output AS BEGIN SET NOCOUNT ON; Set ...
- 使用git整体流程
一.git提交代码走meger请求的整体流程 工作中使用git推代码时,如果走merge请求,那么也就是说拉代码时拉公共代码库的代码,但是提交时需要先提交到自己的代码库,然后在gitlab上提交mer ...
- 经典SQL查询语句大全
一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数 ...
- 【PSR规范专题(2)】PSR-1 基本代码规范
转载自: https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-1-basic-coding-standard-cn.md 基本代码规范 本篇规范制定 ...
- JavaWeb项目开发案例精粹-第4章博客网站系统-002辅助类及配置文件
1. <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5&qu ...
- yafeilinux.com的开源项目非常好的东西
转自:http://www.yafeilinux.com/?page_id=9 声明:我们网站的资源可以自由下载,转载,但是不能用作商业用途.如有问题请联系我们www.yafeilinux.com . ...
- Struts2笔记——类型转换
概述 * 从一个HTML 表单到一个Action 对象, 类型转换是从字符串到非字符串. >HTTP 没有 “类型” 的概念. 每一项表单输入只可能是一个字符串或一个字符串数组. 在服 ...
- [AFN]AFNetworking错误总结
1. 错误打印 code=-1016 filed: text/html 错误原因:AFN默认不能解析请求回来的text/html数据 解决办法: AFN3.0的请看这里 AFHTTPSessionM ...
- CreateFile,WriteFile,ReadFile
注意: CreateFile 跟 fopen 不同,打开文件时不区分 文本方式 或 二进制 方式 ReadFile 或 WriteFile 都是对二进制数据进行操作 HANDLE WINAPI Cre ...
- C++:异常的处理
6.4 异常处理 程序中常见的错误分为两大类:编译时期的错误和运行时期的错误. 编译时期的错误比较简单容易发现:主要是语法错误,如关键字拼写错误.缺分号.括号不匹配等 运行时期的错误比较难发现,甚至是 ...