lcy | We have carefully selected several similar problems for you: 3665 3669 3667 3664 3663
对于一个n*m的矩阵W~想问是否有长的为n的序列a和长度为m的序列b ~~存在对任意L<=W[i][j]*a[i]/b[j]<=U;
一眼望去就知道这是一道~关于构图加spfa判断负环的差分约束~但是刚开始根本不知道怎样构图(话说对于图论一直都是构图难~只要勾完图一个函数就出来~)~ 之后发现只要取对数~就会使式子变成::
log(L)-log(W[i][j])<=log(a[i])-log(b[j])<=log(U)-log(W[i][j]);
将每个log(a[i])和log(b[j])看成点~这里我是将j=j+n~让点不重复~然后你跑一个最短路就好了;
结果就是我T了~~囧~感觉这道题非要用A_Star算法??
感觉就很烦~~于是找了找资料~发现了两个关于spfa的优化~~SLF和LLL(我用了SLF这里,有兴趣可以看https://blog.csdn.net/oranges_c/article/details/64124235);
我现在用的就是SLF~~SLF需要用到双端队列deque~这个存在于
这样优化后就能过了~其实我觉得SLF和A_*在意义上感觉差的不大~像是简化版本??
#include
#include
#include
#include
#include
#include
using namespace std;
#define inf 0x3f3f3f3f
struct fuck
{
int to, ne;
double len;
}ed[500000];
double d[50000];
int cnt = 0;
int head[50000];
void add(int from, int to, double len)
{
ed[cnt].len = len;
ed[cnt].to = to;
ed[cnt].ne = head[from];
head[from] = cnt++;
}
int a, b, mi, ma;
bool vis[50000];
int time[50000];
int spfa()
{
dequeq;
q.push_front(0);
vis[0] = 1;
d[0]=0;
time[0]=1;
while (!q.empty())
{
int t = q.front();//双端队列
q.pop_front();//双端队列的插入弹出有他独特的函数~需要看下;
vis[t] = 0;
for (int s = head[t]; ~s; s = ed[s].ne)
{
if (d[ed[s].to]>d[t] + ed[s].len)
{
d[ed[s].to] = d[t] + ed[s].len;
if (!vis[ed[s].to])
{
vis[ed[s].to] = 1;
if (++time[ed[s].to]>=a + b)
{
return 0;
}
if(!q.empty())//注意队列为空时的处理
{
if(d[ed[s].to]