其中一条路径 (33 L 00)-->(31 R 01)-->(32 L 01)-->(30 R 03)-->(31 L 02)-->(11 R 22)-->(22 L 01)-->(02 R 31)-->(03 L 30)-->(01 R 32)-->(02 L 31)-->(00 R 33) 1、两个吃人恶魔过河 2、一个吃人恶魔回来 3、两个吃人恶魔过河 4、一个吃人恶魔回来 5、两个传教士过河 6、一个传教士和一个吃人恶魔回来 7、两个传教士回来 8、一个吃人恶魔回去 9、两个吃人恶魔过河 10、一个吃人恶魔回去 11、两个吃人恶魔过河
dis[s] = 0; q.push(Node{ s, dis[s] }); while (!q.empty()) { Node x = q.top(); q.pop(); int u = x.u;
if (vis[u]) continue;
vis[u] = true; for (int i = head[u]; i != -1; i = edge[i].next) //松弛与u直接相邻的顶点 { int v = edge[i].to; int w = edge[i].w; if (!vis[v] && dis[u] + w < dis[v]) { dis[v] = dis[u] + w; q.push(Node{ v,dis[v] }); } } } }
constint score[] = { 1,2,5,10 }; //每个人单独行动的时间
intmain() { //建图 memset(head, -1, sizeof(head)); int id = 0; for (int i = 0; i < (1 << 4); i++) { int bits[4]; for (int j = 0; j < 4; j++) bits[j] = (i >> j) & 1; //一次走一个人 for (int j = 0; j < 4; j++) if (bits[j]) { int tmp = i - (1 << j) + 16; int w = score[j]; AddEdge(i, tmp, w, id++); AddEdge(tmp, i, w, id++); } //一次走两个人 for(int j = 0;j < 3;j++) for (int k = j + 1; k < 4; k++) if (bits[j] && bits[k]) { int tmp = i - (1 << j) - (1 << k) + 16; int w = max(score[j],score[k]); AddEdge(i, tmp, w, id++); AddEdge(tmp, i, w, id++); } } Dijsktra(15); printf("%d\n", dis[16]);