題意:有n盆菜,每個菜的上菜時間是ai-bi,要求每盆菜的品嚐時間都相同,求最大的品嚐時間。
思路:一開始也想到了網路流,但是沒有想到壓縮區域。。。(我只想到乙個點乙個點地建圖,這個的圖點可能有10^4個啊。。肯定不能用網路流),後來請教別人可以乙個區間建圖,流量就是區間長度,這個的話點最多300+個。。。網路流妥妥可以。。。。
做法就是找到乙個區間,掃一遍所有的菜哪些菜的上菜時間是包含這個區間的,然後從s到時間區間點連乙個區間長度大小的流量,時間區間點到能到的菜連乙個區間長度大小的流量,最後一遍最大流搞定。
ps:神奇的貪心做法可以二分最大品嚐時間,每次掃瞄乙個單位的區間然後把這個區間分給bi最小且品嚐時間沒滿的菜,就這樣好了。。。。
#include#define mem(a,b) memset(a,b,sizeof(a))
#define for(a,b,c) for(int a = b;a <= c;a++)
using namespace std;
typedef long long ll;
const int maxn = 1000005;
const int inf = 0x3f3f3f3f;
const int e_maxn = 100000 * 4;
const int v_maxn = 500;
struct ppp
e[e_maxn];
int head[v_maxn],dis[v_maxn],cur[v_maxn];//煉表頭節點,層次圖中每個點所屬層次,dfs所用的臨時煉表頭
int tole,n,m,s,t;//總加入邊數,總輸入點數和總輸入邊數,源點和匯點
void make_edge(int u,int v,int cap,int c)//求最大流時費用不必考慮,可以省去,加上也沒關係
void add_edge(int u,int v,int cap,int c)
int bfs()//其中s為源點,t為匯點
} }return dis[t] != -1;
}int dfs(int x,int a)
} return ret;
}void dinic(int &ans)//ans為最大流
}int mark[10005];
int n;
int a[105],b[105];
int cal(int x)
add_edge(cnt,300 + j,i - from,0);}}
from = i;
} }for(int i = 0;i < n;i++)
add_edge(300 + i,t,x,0);
int ans = 0;
dinic(ans);
if(ans == x * n)return 1;
else return 0;
}int main()
int l = 0,r = minn;
int ans = 0;
while(l <= r)
else r = mid - 1;
} printf("%d\n",ans * n);
}}
CF589H 構造 電話節
鏈結找不到了 發現如果對於乙個聯通塊內的偶數個點,一定可以兩兩配對且不相交 如果相交,則調換組合順序一定可以不相交 而如果我們把所有這些路徑拿出來,邊數一定小於等於聯通塊大小 1 所以直接在任意生成樹上做就好 那麼就dfs一下,判斷一下有沒有奇數個點就好了 dfs過程中,乙個點的子樹中的點最多向上傳...
解題報告 CF622F
懶得碼字了 很簡單的數論題,紫題顯然是過了些,不要說.對於這個式子,是乙個 k 1 次的多項式,插 k 2 次值就好了,煩人的是處理逆元,我的費馬小定理顯然是 o logp 的,可以用拓歐,聽說還有 o k 的演算法,我似乎感覺不太可能 我太弱了 預處理處階乘,前 字尾積陣列即可,複雜度 o klo...
CF1475F 異常矩陣
原題鏈結 有兩個 0 1 矩陣 a,b,存在兩種操作 1 選擇一列,將這列的元素 xor 1。2 選擇一行,將這行的元素 xor 1。判斷是否存在操作使得矩陣 a 能轉化為矩陣 b。由異或的性質,我們可以得到兩點結論。1 操作的順序不影響結果。2 操作最多只能進行一次。根據這兩點,我們可以根據第一行...