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<int> g[maxn] ;
int mind[maxn] ;//0點到其他點的最短路徑
int dijkstra(){
int i , j ;
priority_queue<Node> 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 ;
}
OJ題目:click here~~
題目分析:基本的dijkstra算法,多了一個花費,在路徑相等時 根據 花費更新即可
AC_CODE
const int maxn = 1008 ;
const int inf = 1<<30 ;
vector<int> g[maxn] ;
int len[maxn][maxn] ;
int cost[maxn][maxn] ;
int dis[maxn] ;
int val[maxn] ;
int vis[maxn] ;
int s , t ;
typedef pair<int , int > pii ;
void dijkstra(){
priority_queue<pii , vector<pii> , greater<pii> > 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<int> 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<Node> 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 ;
}