<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      P7086 題解

      考慮把每個字符串的前 \(k\) 位和后 \(k\) 位看成點,字符串看成邊,那么一個字符串前綴后綴至少有一個是相似群體的前綴后綴,看成這條邊的兩個端點至少有一個被選中。

      那么這就變成了一個最小點覆蓋問題。

      考慮匈牙利算法算出答案,然后考慮如何構造答案。

      考慮右邊沒有被匹配的點,選中這些點向左邊連的點,因此這個點本身就不用被選中,考慮左邊剛剛被選中的點,它們在右邊匹配的點就不用選了,那么它們在右邊匹配的點就進入右邊沒有被匹配的點相同的流程,如此遞歸下去,那么左邊便利到的點就會被選中,右邊被遍歷到的點就不會被選中。

      如此便可以構造出選中的點,然后再分配字符串到集合即可。

      #include<bits/stdc++.h>
      #define int unsigned long long
      using namespace std;
      
      const int maxn = 1e6+114;
      const int base = 1145141;
      int vis[maxn],match[maxn];
      vector<int> edge[maxn],fedge[maxn];
      map<int,int> road[2][maxn];
      int ans;
      int fm[maxn];
      bool hungary(int u){
      	for(int v:edge[u]){
      		if(vis[v]==1) continue;
      		vis[v]=1;
      		if(match[v]==0||hungary(match[v])==true){
      			match[v]=u;
      			fm[u]=v;
      			return true;
      		}
      	}
      	return false;
      }
      
      int pre[maxn],suf[maxn];
      
      int n,k,cnt;
      map<int,int> f;
      map<int,int> p[2];
      vector<int> chifan[2];
      int use[maxn][2];
      
      vector<int> answer[2];
      map<int,int> pos[2];
      
      int op[maxn][2];
      vector<int> OUT[maxn][2];
      void dfs(int u,int type){
      	if(op[u][type]==1) return ;
      	op[u][type]=1;
      	if(type==0){
      		dfs(fm[u],1);
      	}
      	else{
      		for(int nxt:fedge[u]){
      			if(nxt!=match[u]){
      				dfs(nxt,0);
      			}
      		}
      	}
      }
      signed main(){
      	cin>>n>>k;
      	for(int i=1;i<=n;i++){
      		string s;
      		cin>>s;
      		for(int j=0;j<k;j++){
      			pre[i]=pre[i]*base+s[j];
      		}
      		for(int j=s.size()-1;j>=s.size()-k&&j<s.size();j--){
      			suf[i]=suf[i]*base+s[j];
      		}
      		if(f[pre[i]]==0){
      			f[pre[i]]=++cnt;
      		}
      		if(p[0][f[pre[i]]]==0)
      			chifan[0].push_back(f[pre[i]]),p[0][f[pre[i]]]=1;
      		if(f[suf[i]]==0){
      			f[suf[i]]=++cnt;
      		}
      		if(p[1][f[suf[i]]]==0)
      			chifan[1].push_back(f[suf[i]]),p[1][f[suf[i]]]=1;
      		edge[f[pre[i]]].push_back(f[suf[i]]),fedge[f[suf[i]]].push_back(f[pre[i]]);
      	}
      	for(int i:chifan[0]){
      		memset(vis,0,sizeof(vis));
      		if(hungary(i)==true) ans++;
      	}
      	for(int i:chifan[1]){
      		if(match[i]==0){
      			dfs(i,1);
      		}
      	}
      	for(int i=1;i<=n;i++){
      		if(op[f[pre[i]]][0]==1){
      			OUT[f[pre[i]]][0].push_back(i);
      		}
      		else if(op[f[suf[i]]][1]==0){
      			OUT[f[suf[i]]][1].push_back(i);
      		}
      	}
      	cout<<ans<<'\n';
      	for(int i:chifan[0]){
      		if(op[i][0]==1){
      			cout<<OUT[i][0].size()<<' ';
      			for(int j:OUT[i][0]) cout<<j<<' ';
      			cout<<'\n';
      		}
      	}
      	for(int i:chifan[1]){
      		if(op[i][1]==0){
      			cout<<OUT[i][1].size()<<' ';
      			for(int j:OUT[i][1]) cout<<j<<' ';
      			cout<<'\n';
      		}
      	}
      	return 0;
      }
      
      posted @ 2024-02-27 18:11  ChiFAN鴨  閱讀(47)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 彩票| 风韵丰满熟妇啪啪区老熟熟女| 国产午夜福利片在线观看| 亚洲蜜臀av乱码久久| 久久久久久伊人高潮影院| 成人午夜精品无码区久久| 少妇性bbb搡bbb爽爽爽欧美| 黄色亚洲一区二区三区四区| 精品国产免费人成在线观看| 无码熟妇人妻av影音先锋| 亚洲人成人网站色www| 中文亚洲成A人片在线观看| 黄瓜视频在线观看| 国产精品久久人妻无码网站一区| 国产精品成人午夜久久| 精品人妻系列无码天堂| 视频一区视频二区在线视频| 精品国产亚洲一区二区三区| 欧美激情 亚洲 在线| 老司机亚洲精品一区二区| 国产av一区二区亚洲精品| 免费无码黄十八禁网站| av无码一区二区大桥久未| 国产精品福利自产拍久久| 亚洲aⅴ天堂av天堂无码麻豆| 国产亚洲精品aaaa片app| 亚洲夜色噜噜av在线观看| 国产老熟女国语免费视频| 伊人久久大香线蕉网av| 国产午夜福利不卡在线观看| 国产一区二区三区精品综合| 亚洲精品成人久久av| 国产成人啪精品视频免费网| 国产suv精品一区二区33| 在线成人| 91福利视频一区二区| 成人亚洲欧美成αⅴ人在线观看| 加勒比色综合久久久久久久久| 白嫩少妇无套内谢视频| 欧美牲交a欧美在线| 亚洲成人免费一级av|