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 };

 

posted @ 2018-07-14 16:29  双零  阅读(234)  评论(0)    收藏  举报