HDU4598 Difference(差分約束)

2021-08-22 10:21:24 字數 2170 閱讀 2514

題意:

有乙個圖,給圖上每個頂點都賦乙個實數ai。如果存在乙個正整數t滿足下面兩個條件,這個圖就是乙個"difference"。

1. |ai| <= t。

2. 如果點i,j構成的邊在圖中存在,則 |ai - aj| >= t;否則 |ai - aj| " 代表充要條件)

給出圖,問這個圖是否是乙個"difference"。

思路:

結合前兩個條件,顯然每條邊的兩個端點值都要一正一負,用dfs給每個頂點打上標記colors(1表示值為正,2表示值為負)。

如果圖中存在奇數邊的環一定無解,可以在dfs的時候進行剪枝,能夠讓執行時間快一大半。

然後是遍歷每個點對(i,j),有下面四種情況:

1. 邊ij存在,且點i為正,則 ai - aj >= t

2. 邊ij存在,且點i為負,則 aj - ai >= t

3. 邊ij不存在,且點i為正,則 ai - aj <= t - 1

4. 邊ij不存在,且點i為負,則 aj - ai <= t - 1

僅僅是上面的不等式建的圖不一定連通,我們可以增加超級源點0,設a0 = 0,那麼就有下面兩種情況:

1. 點i為正時,0 <= ai - a0 <= t - 1

2. 點i為負時,0 <= a0 - ai <= t - 1

t的值不重要,取超過點數即可。

用上面兩組不等式建圖,然後spfa判負環即可。

#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int maxn = 1005;

struct edgg[90005];

int tot, pre[305];

void add(int u, int v, int w)

int g[305][305], flag, n, times[305], colors[305], dis[305];

bool vis[305];

void dfs(int x, int k)

colors[x] = k;

vis[x] = true;

for (int i = 1; i <= n; ++i) else }}

if (flag)

}}bool spfa()

times[0] = 1;

vis[0] = true;

dis[0] = 0;

queueque;

que.push(0);

while (!que.empty())

vis[v] = true;

que.push(v);}}

}}return true;

}int main()

}flag = 0;

memset(colors, 0, sizeof(colors));

memset(vis, 0, sizeof(vis));

for (int i = 1; i <= n; ++i)

if (flag) break;

}if (flag)

tot = 0;

memset(pre, -1, sizeof(pre));

for (int i = 1; i <= n; ++i) else

} else else }}

if (colors[i] == 1) else

}puts(spfa() ? "yes" : "no");

}return 0;

}

這道題只用差分約束,不寫判奇環也能過,但時間要慢一些。下面乙個是帶剪枝的,上面乙個是不判奇環的。

BZOJ HNOI2005 狡猾的商人(差分約束)

time limit 10 sec memory limit 162 mb submit 4969 solved 2496 submit status discuss 刁奼接到乙個任務,為稅務部門調查一位商人的賬本,看看賬本是不是偽造的。賬本上記錄了n個月以來的收入情況,其中第i 個月的收入額為ai...

BZOJ HNOI2005 狡猾的商人(差分約束)

time limit 10 sec memory limit 162 mb submit 4969 solved 2496 submit status discuss 刁奼接到乙個任務,為稅務部門調查一位商人的賬本,看看賬本是不是偽造的。賬本上記錄了n個月以來的收入情況,其中第i 個月的收入額為ai...

差分約束 hdu 3666

xij ai l bj 0 xij ai u bj 0 兩邊取對數來去除ai,bj前面的係數 有 logbj logai logxij logu logai log bj logl logxij 化成標準差分約束,建圖,spfa,注意乙個竅門,當入隊總數大於2 n m 時就可以輸出no 因為 乙個點...