2019/03/18 完成01-02
2019/03/19 完成03
2019/03/20 完成04
2019/03/21 完成05(unordered_set)
2019/03/22 完成05(手写哈希),06
2019/03/23 完成07
2020/07/30 完成08,09
2020/07/31 补充08标准解法:Manacher算法
L2-001 紧急救援(C++11)
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
using intpair = pair<int, int>;
const int INF{0x3f3f3f3f};
int main(int argc, char *argv[])
{
cin.sync_with_stdio(false);
int N, M, S, D;
cin >> N >> M >> S >> D;
vector<int> vec(N);
for (int i = 0; i != N; ++i)
cin >> vec[i];
vector<vector<intpair>> road(N);
for (int i = 0; i != M; ++i)
{
int mbeg, mend, mvel;
cin >> mbeg >> mend >> mvel;
road[mbeg].push_back({mend, mvel});
road[mend].push_back({mbeg, mvel});
}
vector<int> dijkstra(N, INF), mov(N), cross(N), mins(N);
vector<bool> known(N, false);
dijkstra[S] = 0;
mov[S] = vec[S];
cross[S] = -1;
mins[S] = 1;
while (1)
{
int minval{INF}, minindex{-1};
for (int i = 0; i != N; ++i)
{
if (known[i] == false && dijkstra[i] != INF && dijkstra[i] < minval)
{
minindex = i;
minval = dijkstra[i];
}
}
if (minindex == -1)
break;
known[minindex] = true;
for (const auto &i : road[minindex])
{
if (dijkstra[minindex] + i.second < dijkstra[i.first])
{
dijkstra[i.first] = dijkstra[minindex] + i.second;
mov[i.first] = mov[minindex] + vec[i.first];
cross[i.first] = minindex;
mins[i.first] = mins[minindex];
}
else if (dijkstra[minindex] + i.second == dijkstra[i.first])
{
if (mov[minindex] + vec[i.first] > mov[i.first])
{
mov[i.first] = mov[minindex] + vec[i.first];
cross[i.first] = minindex;
}
mins[i.first] += mins[minindex];
}
}
}
cout << mins[D] << ' ' << mov[D] << endl;
stack<int> ST;
int tD{D};
ST.push(D);
while (cross[tD] != -1)
{
ST.push(cross[tD]);
tD = cross[tD];
}
bool fis = true;
while (!ST.empty())
{
if (fis)
fis = false;
else
cout << ' ';
cout << ST.top();
ST.pop();
}
cout << endl;
return EXIT_SUCCESS;
}
Dijkstra算法
L2-002 链表去重(C++11)
#include <iostream>
#include <vector>
using namespace std;
using intpair = pair<int, int>;
int main(int argc, char *argv[])
{
int beginnode, cnt;
scanf("%d%d", &beginnode, &cnt);
vector<intpair> LinkNode(100000);
vector<int> book(100001);
while (cnt--)
{
int beg, val, next;
scanf("%d%d%d", &beg, &val, &next);
LinkNode[beg] = {val, next};
}
int disp{-1}, dispold{beginnode}, temp{-1}, temp2{-1};
while (beginnode != -1)
{
if (book[abs(LinkNode[beginnode].first)])
{
if (disp == -1)
disp = temp = beginnode;
else
{
LinkNode[temp].second = beginnode;
temp = beginnode;
}
}
else
{
if (temp2 != -1)
LinkNode[temp2].second = beginnode;
temp2 = beginnode;
book[abs(LinkNode[beginnode].first)] = true;
}
beginnode = LinkNode[beginnode].second;
}
LinkNode[temp2].second = LinkNode[temp].second = -1;
beginnode = dispold;
if (beginnode != -1)
{
printf("%05d %d", beginnode, LinkNode[beginnode].first);
beginnode = LinkNode[beginnode].second;
while (beginnode != -1)
{
printf(" %05d\n%05d %d", beginnode, beginnode, LinkNode[beginnode].first);
beginnode = LinkNode[beginnode].second;
}
printf(" -1\n");
}
beginnode = disp;
if (beginnode != -1)
{
printf("%05d %d", beginnode, LinkNode[beginnode].first);
beginnode = LinkNode[beginnode].second;
while (beginnode != -1)
{
printf(" %05d\n%05d %d", beginnode, beginnode, LinkNode[beginnode].first);
beginnode = LinkNode[beginnode].second;
}
printf(" -1\n");
}
return EXIT_SUCCESS;
}
考察数组模拟链表;上面的实现的稍有麻烦,完全修正了链表地址,分开了两个链表;然而根据题目输出要求,这是没有必要的!可以直接开两个vector存储下两个链表的地址,如下。
#include <iostream>
#include <vector>
using namespace std;
using intpair = pair<int, int>;
intpair LinkNode[100000];
int book[100001]{0};
int main(int argc, char *argv[])
{
int beginnode, cnt;
scanf("%d%d", &beginnode, &cnt);
while (cnt--)
{
int beg, val, next;
scanf("%d%d%d", &beg, &am