蒟蒻刚刚搞清楚同余最短路是个咋回事就被这个题教训了……
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int inf = 999999999;
struct node
{
int id;
int dis;
bool operator <(const node &b)const
{
return dis > b.dis;
}
};
int dis[3005], length[3005], tot;
bool vis[3005];
bool judge()//判断是否无解的一种情况:最小公约数大于等于2
{
for (int i = 2; i <= tot; i++)
if(length[i]%length[1]!=0)
return 0;
return 1;
}
void dijkstra(int s)//dijkstra的板子
{
dis[s] = 0;
priority_queue<node> q;
q.push((node){s, 0});
while(!q.empty())
{
node tp = q.top();
q.pop();
if(vis[tp.id])
continue;
vis[tp.id] = 1;
for (int i = 2; i <= tot;i++)//不敢建边了,开到了五千万的边数组还是RE了
if(dis[(tp.id+length[i])%length[1]]>dis[tp.id]+length[i])
{
dis[(tp.id + length[i]) % length[1]] = dis[tp.id] + length[i];
q.push((node){(tp.id + length[i]) % length[1], dis[(tp.id + length[i]) % length[1]]});
}
}
return;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n;i++)
{
int place = ++tot;//初始边所在位置
scanf("%d", &length[tot]);
for (int j = 1; j <= m && j < length[place]; j++)//切下来长度最长不能超过远长
length[++tot] = length[place] - j;//切的木棍长度
}
sort(length + 1, length + tot + 1);
if(length[1]==1 || judge())//当最小长度为1时所有长度均可表示,直接-1
{
printf("-1");
return 0;
}
for (int i = 0; i < length[1]; i++)
dis[i] = inf;
dijkstra(0);
int res = -1;
for (int i = 1; i < length[1]; i++)//枚举最大长度
res = max(res, dis[i]);
printf("%d", res - length[1]);
return 0;
}