題目大意:
給定n
nn個字串,要求我們從每個字串中選出乙個子串行(可以不連續)。
要求每個選出的子串行都不同,並使得最長的最序列最短。
要求輸出所求答案,並輸出一組可行解。
n
≤300
n≤300
n≤30
0,每個字串長度不超過300.
分析:對於每乙個字串來說,只有前n
nn長的子串行有用,因為無論如何都可以選到乙個。
可以構建序列自動機,然後bfs求出前n
nn長的子串行。
然後對每個不同的子串行開乙個點,每個字串也開乙個點,每個字串向他有的子串行連一條邊。
我們先二分答案,然後把長度大於mid
midmi
d的點去掉,然後跑最大流是否左邊的點都可以被匹配。
輸出方案需要先把網路重置到ans
ansan
s時的網路,然後再跑一次最大流,看字串向子串行的邊是否有流量流過。
去重可以考慮對子序列進行hash+map。因為一定存在乙個以當前子串行為字首,而且長度少1的子串行。儲存所有子串行時,我們可以把當前子串行指向字首的那個子串行,並記錄下多的這個位置是哪個字元,輸出只需要遞迴處理即可。
這樣時間和空間都比較優秀,複雜度是o(n
3log
n)
o(n^3logn)
o(n3lo
gn)的。
**:
#include #include #include #include #include #include #define ll long long
const int l=357;
const int maxn=1e5+7;
const int maxe=3e5+7;
const ll mod[2]=;
using namespace std;
int n,cnt,tot,s,t,maxlen;
int next[l][26],ls[maxn],dis[maxn];
char s[l][l];
struct edgeg[maxe];
struct rec;
bool operator <(rec a,rec b)
a[maxn];
void add(int x,int y,int w)
; ls[x]=tot;
g[++tot]=(edge);
ls[y]=tot;
}bool bfs()}}
return false;
}int dfs(int x,int maxf)
}return ret;
}void solve(int i)
); int tmp=0;
while (!q.empty())
; maxlen=max(maxlen,a[cnt].len);
h[d]=cnt;
}int e=h[d];
add(i,e+n,1);
q.push((rec));
tmp++;
if (tmp>=n) return;
}} }
}int dinic()
void prework()
solve(i);
} s=0,t=n+cnt+1;
for (int i=1;i<=n;i++) add(s,i,1);
for (int i=1;i<=cnt;i++) add(n+i,t,1);
}void wri(int x)
int main()
for (int i=1;i<=cnt;i++)
}if (dinic()>=n) ans=mid,r=mid-1;
else l=mid+1;
} printf("%d\n",ans);
if (ans>0)
for (int i=1;i<=cnt;i++)
}dinic();
for (int i=1;i<=n;i++)
}} }
}
不同的縮寫
題目描述 你在寫一款 galgame 的劇情 的 在這個遊戲中一共有 n 個角色。你需要編寫一些關於這些角色的對話內容。然而,在寫這些對話內容之前,都要寫一段關於角色資訊的 就像這樣 character alex color fffc3a 你覺得這樣好麻煩。你決定把它簡化一下。你打算用角色名字的乙個...
JZOJ 3910 Idiot 的間諜網路
作為一名高階 idiot 苦心經營多年,終於在敵國建立起一張共有n 名 的龐大間諜網路。當然,出於保密性的要求,間諜網路中的每名 最多隻會有一名直接領導。現在,idiot 希望整理有關歷次特別行動的一些資訊。初始時,間諜網路中的所有 都沒有直接領導。之後,共有m 次下列型別的事件按時間順序依次發生 ...
相同網路與不同網路間的通訊解釋!
1 本機ip位址與本機子網掩碼進行與運算,得出網路號。2 目標ip位址與本機子網掩碼進行與運算得出網路號。3 觀察兩個網路號是否相同。4 對方主機同樣進行1 3的計算 又因為通訊是雙向的,所以兩台主機都必須 各自 認為它們屬於相同網段,那麼資料才能往返。倘若把b主機的子網掩碼改為255.255.25...