Topcoder DesertWind 最短路转移dp 优化
这题与WarTransportation很像,也可以理解为两人博弈
dp[i][j]=min(dp[i1][j1]+3,dp[i2][j2]+3) 其中(i1,j1)为(i,j)所有邻居中dp[i'][j']最小的(i',j'),(i2,j2)为(i,j)所有邻居中dp[i'][j']次小的(i',j')
考虑到方程转移有环,直接最短路(对map的运用要熟悉啊!虽然其实不用map)
我的时间复杂度为O(n²log² n²)
其实可以O(n²log n²)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define PII pair<int,int> 4 #define PPII pair<int,pair<int,int> > 5 #define mp make_pair 6 struct Nodedp 7 { 8 map<PII,int> m; 9 int value; 10 int getvalue() 11 { 12 map<PII,int>::iterator it=m.begin(); 13 int fir=1e9,sec=1e9; 14 for(;it!=m.end();it++) 15 { 16 if(it->second<fir) 17 { 18 sec=fir; 19 fir=it->second; 20 } 21 else if(it->second<sec) sec=it->second; 22 } 23 int val; 24 if(fir!=1e9&&sec!=1e9) val=min(fir+3,sec+1); 25 else if(fir!=1e9) val=fir+3; 26 else val=0; 27 value=val; 28 return val; 29 } 30 }; 31 struct DesertWind 32 { 33 Nodedp dp[55][55]; 34 string s[505]; 35 vector<PII>nei[55][55]; 36 int daysNeeded(vector<string> theMap) 37 { 38 int n,m; 39 priority_queue<PPII> q; 40 n=theMap.size(); 41 m=theMap[0].size(); 42 for(int i=0;i<n;i++) 43 { 44 s[i]=theMap[i]; 45 } 46 for(int i=0;i<n;i++) 47 { 48 for(int j=0;j<m;j++) 49 { 50 if(s[i][j]=='X') continue; 51 if(s[i][j]=='*') 52 { 53 q.push(mp(0,mp(i,j))); 54 dp[i][j].value=0; 55 } 56 else dp[i][j].value=1e9; 57 for(int i1=i-1;i1<=i+1;i1++) 58 { 59 for(int j1=j-1;j1<=j+1;j1++) 60 { 61 if(i1<0||j1<0||i1>=m||j1>=m||s[i1][j1]=='X') continue; 62 nei[i][j].push_back(mp(i1,j1)); 63 } 64 } 65 } 66 } 67 while(!q.empty()) 68 { 69 PPII tmp=q.top();q.pop(); 70 int x=tmp.second.first; 71 int y=tmp.second.second; 72 int cost=-tmp.first; 73 if(cost!=dp[x][y].value) continue; 74 // cout<<x<<" "<<y<<" "<<cost<<endl; 75 for(int i=0;i<nei[x][y].size();i++) 76 { 77 int x1=nei[x][y][i].first,x2=nei[x][y][i].second; 78 Nodedp dptmp=dp[x1][x2]; 79 dptmp.m[mp(x,y)]=cost; 80 int gv=dptmp.getvalue(); 81 if(gv<dp[x1][x2].value) 82 { 83 dp[x1][x2]=dptmp; 84 q.push(mp(-dp[x1][x2].value,mp(x1,x2))); 85 } 86 } 87 } 88 for(int i=0;i<n;i++) 89 { 90 for(int j=0;j<m;j++) 91 { 92 if(s[i][j]=='@') 93 { 94 if(dp[i][j].value!=1e9) return dp[i][j].value; else return -1; 95 } 96 } 97 } 98 } 99 };
我们也可以考虑,从终点向起点考虑,设VT节点最快在时间为T时能到终点,
①有大于等于2个VT的邻居为u,则可以在第T+1天到u
②有1个VT和1个VT+1的邻居为u,可以在第T+2天到u
③否则可以在T+3天到u
复杂度为O(n²)
不知道为什么这里用queue的效率低于直接用priority_queue,于是怒写一发手写queue,最后也没比priority_queue快多少。。。
一定要会写链表!
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mp make_pair 4 struct Node 5 { 6 pair<int,int> data; 7 Node *next; 8 }; 9 struct Queue 10 { 11 Node *head; 12 Node *la; 13 Queue() 14 { 15 head=(Node *)malloc(sizeof (Node)); 16 la=(Node *)malloc(sizeof (Node)); 17 head =NULL; 18 } 19 bool empty() 20 { 21 if(head==NULL) return 1; 22 else return 0; 23 } 24 void push(pair<int,int> x) 25 { 26 Node *p1; 27 p1=(Node *)malloc(sizeof (Node)); 28 p1->data=x; 29 if(head==NULL) 30 { 31 head=p1; 32 la=p1; 33 } 34 else 35 { 36 la->next=p1; 37 la=p1; 38 } 39 la->next=NULL; 40 } 41 void pop() 42 { 43 Node *p1; 44 p1=head->next; 45 delete head; 46 head=p1; 47 } 48 pair<int,int> front() 49 { 50 return head->data; 51 } 52 }; 53 struct DesertWind 54 { 55 bool hadvis[55][55],willvis[55][55]; 56 priority_queue<pair<int,int> > q[7505]; 57 string s[55]; 58 int dp[55][55]; 59 vector<pair<int,int> > nei[55][55]; 60 int daysNeeded(const vector<string> &theMap) 61 { 62 int n,m; 63 n=theMap.size(); 64 m=theMap[0].size(); 65 for(int i=0;i<n;i++) 66 { 67 s[i]=theMap[i]; 68 } 69 for(int i=0;i<n;i++) 70 { 71 for(int j=0;j<m;j++) 72 { 73 if(s[i][j]=='X') continue; 74 if(s[i][j]=='*') 75 { 76 q[0].push(mp(i,j)); 77 dp[i][j]=0; 78 } 79 else dp[i][j]=1e9; 80 for(int i1=i-1;i1<=i+1;i1++) 81 { 82 for(int j1=j-1;j1<=j+1;j1++) 83 { 84 if(i1<0||j1<0||i1>=m||j1>=m||s[i1][j1]=='X') continue; 85 nei[i][j].push_back(mp(i1,j1)); 86 } 87 } 88 } 89 } 90 for(int register i=0;i<3*n*m+2;i++) 91 { 92 if(q[i].empty()&&q[i+1].empty()&&q[i+2].empty()&&q[i+3].empty()) 93 break; 94 while(!q[i].empty()) 95 { 96 int x=q[i].top().first,y=q[i].top().second; 97 q[i].pop(); 98 if(hadvis[x][y]||i!=dp[x][y]) continue; 99 if(s[x][y]=='@') 100 { 101 return i; 102 } 103 hadvis[x][y]=1; 104 for(int j=0;j<nei[x][y].size();j++) 105 { 106 int x1=nei[x][y][j].first,y1=nei[x][y][j].second; 107 if(hadvis[x1][y1]) continue; 108 if(i+1<dp[x1][y1]&&dp[x1][y1]!=1e9) 109 { 110 q[i+1].push(make_pair(x1,y1)); 111 dp[x1][y1]=i+1; 112 } 113 else 114 { 115 if(dp[x1][y1]==1e9) 116 { 117 q[i+3].push(make_pair(x1,y1)); 118 dp[x1][y1]=i+3; 119 } 120 } 121 } 122 } 123 } 124 return -1; 125 } 126 };

浙公网安备 33010602011771号