dijkstra
OJ题目:click here~~
题目分析:从0点出发,走遍能走的点的最短路径,可回头。dijkstra算法的变形,求0点出发的能到达的点的最短路径的最大值。2*总路径-最大值 即为要求的值
我只能说,写代码这事,不能停,停了就忘,忘了就出现bug,然后就陷入深深的debug中。。。被折磨的很惨很惨。。
AC_CODE
const int maxn = 52 ;
const int inf = 1<<30 ;
struct Node{
int to , d ;
Node(){}
Node(int a , int b):to(a),d(b){}
friend bool operator<(const Node &A , const Node &B){
return A.d > B.d ;
}
};
int dis[maxn][maxn] ;
vector g[maxn] ;
int mind[maxn] ;//0点到其他点的最短路径
int dijkstra(){
int i , j ;
priority_queue que ;
que.push(Node(0 , 0)) ;
mind[0] = 0 ;
while(!que.empty()){
Node now = que.top() ; que.pop() ;
int u = now.to ;
if(mind[u] < now.d) continue ;
for(int i = 0;i < g[u].size();i++){
int v = g[u][i] ;
if(mind[v] > now.d + dis[u][v]){
mind[v] = now.d + dis[u][v] ;
que.push(Node(v , mind[v])) ;
}
}
}
int ans = 0 ;
for(int i = 0;i < maxn;i++){
if(mind[i] != inf)
ans = max(ans , mind[i]) ;
}
return ans ;
}
int main(){
int n , u , v , x , i , j ;
int sum ;
//freopen("in.txt","r",stdin) ;
while(scanf("%d",&n) != EOF){
sum = 0 ;
fill(mind , mind + maxn , inf) ;
for(i = 0;i < maxn;i++)
g[i].clear() ;
for(i = 0;i < n;i++){
scanf("%d%d%d",&u,&v,&x) ;
g[u].push_back(v) ;
g[v].push_back(u) ;
dis[u][v] = dis[v][u] = x ;
sum += x ;
}
int ans = dijkstra() ;
printf("%d\n",2*sum - ans) ;
}
return 0 ;
}
题目分析:基本的dijkstra算法,多了一个花费,在路径相等时 根据 花费更新即可
AC_CODE
const int maxn = 1008 ;
const int inf = 1<<30 ;
vector g[maxn] ;
int len[maxn][maxn] ;
int cost[maxn][maxn] ;
int dis[maxn] ;
int val[maxn] ;
int vis[maxn] ;
int s , t ;
typedef pair pii ;
void dijkstra(){
priority_queue , greater > que ;
que.push(make_pair(0 , s)) ;
while(!que.empty()){
pii now = que.top() ; que.pop() ;
int u = now.second ;
if(dis[u] < now.first) continue ;
for(int i = 0;i < g[u].size();i++){
int v = g[u][i] ;
if(dis[v] > dis[u] + len[u][v]){
dis[v] = dis[u] + len[u][v] ;
val[v] = val[u] + cost[u][v] ;//printf("%d~~~~",val[v]) ;
que.push(make_pair(dis[v] , v)) ;
}
else if(dis[v] == dis[u] + len[u][v] && val[v] > val[u] + cost[u][v]){
val[v] = val[u] + cost[u][v] ;
que.push(make_pair(dis[v] , v)) ;
}
}
}
}
int main(){
int n , m , i , j , u , v , d , c;
//freopen("in.txt","r",stdin) ;
while(cin >> n >> m){
if(n == 0 && m == 0) break ;
for(i = 0;i < maxn;i++) g[i].clear() ;
fill(dis , dis + maxn , inf) ;
fill(val , val + maxn , inf) ;
for(i = 0;i < m;i++){
scanf("%d%d%d%d",&u,&v,&d,&c) ;
g[u].push_back(v) ;
g[v].push_back(u) ;
len[u][v] = len[v][u] = d ;
cost[u][v] = cost[v][u] = c ;
}
scanf("%d%d",&s,&t) ;
dis[s] = val[s] = 0 ;
dijkstra() ;
printf("%d %d\n",dis[t],val[t]) ;
}
}
题目分析:就是dijkstsra,但是距离太大,不能用数表示,转化成string来处理
AC_CODE
const int maxn = 108 ;
const int maxm = 508 ;
const int MOD = 100000 ;
int n , m ;
string dis[maxn] ;
int cost[maxn][maxn] ;
int vis[maxn] ;
vector g[maxn] ;
struct Node{
string len ;
int p ;
Node(){
len = string(m , '0') ;
}
bool friend operator<(const Node &A , const Node &B){
return A.len > B.len ;
}
};
void bfs(){
priority_queue que ;
Node nu = Node() ;
nu.p = 0 ;
que.push(nu) ;
int i , j ;
while(!que.empty()){
Node now = que.top() ; que.pop() ;
int u = now.p ;
vis[u] = 1 ;
for(i = 0;i < g[u].size() ;i++){
int v = g[u][i] ;
if(vis[v]) continue ;
string nowstr = now.len ;
nowstr[cost[u][v]] = '1' ;
if(dis[v] > nowstr){
dis[v] = nowstr ;
Node nuu = Node() ;
nuu.p = v ;
nuu.len = nowstr ;
que.push(nuu) ;
}
}
}
return ;
}
int cal(string s){
int ans = 0 ;
for(int i = 0;i < m;i++){
ans = (ans*2 + (s[i] - '0'))%MOD ;
}
return ans ;
}
int main(){
int i , j , k , u , v ;
while(cin >> n >> m){
for(i = 0;i < maxn;i++) g[i].clear() ;
for(i = 0;i < n;i++){
dis[i] = string(m , '2') ;
}
memset(vis , 0 , sizeof(vis)) ;
for(i = 0;i < m;i++){
scanf("%d%d" , &u , &v) ;
g[u].push_back(v) ;
g[v].push_back(u) ;
cost[u][v] = cost[v][u] = m - 1 - i ;
}
dis[0] = string(m , '0') ;
bfs() ;
string ss = string(m , '2') ;
for(i = 1;i < n;i++){
if(dis[i] == ss) puts("-1") ;
else cout << cal(dis[i]) << endl ;
}
}
return 0 ;
}