团结就是力量

团结就是力量

https://ac.nowcoder.com/acm/problem/14411

字符串同构,tarjan,hash

题意:

图片说明

分析:

不难想到用tarjan算法,将互相愿意组队的人员划分出来。但是,稍微有困难把你的便是:如何计算这只队伍的团结系数呢?

这里牵扯到了一个知识点:字符串同构!!
对于字符串a,和字符串b我们知道a经过一定的循环就会变成b。我们称a与b同构。
那么倘若我们将a,b都变为其最小的同构字符串c。
然后我们统计又多少人是同构字符串时,直接用hash表统计c的个数不就好了吗?

关键是如何变为最小的同构字符串呢?
这里给出代码:

string getmin(string s) {
    int len = s.size();int i = 0, j = 1, k = 0;
    while(i < len && j < len && k < len) {
        if (s[(i + k) % len] == s[(j + k) % len])k++;
        else if (s[(i + k) % len] > s[(j + k) % len])i = i + k + 1, k = 0;
        else if (s[(i + k) % len < s[(j + k) % len]])j = j + k + 1, k = 0;
        if (i == j)j++;
    }return (s + s).substr(min(i, j), len);
}

简单的说一下:上面又三个指针:i,j,k
分别意味着从i开始的同构字符串,从j开始的同构字符串,k就是个长度。

那么我们在每一个训话中比较的就是s[i+k],s[j+k]
即是以i开始的同构字符串和以j开始的同构字符串比较第k位。
如果第k位相等,那么k++我们比较k+1位

如果s[i+k]>s[j+k]那么我们知道了以i开始的字符串绝对不是最小同构字符串!
但是,同时我们还知道了以i+1,i+2,i+3。。。。。。i+k开始的同构字符串都不是最小字符串!
为什么这样呢?
我们假设从i+h开始,0<=h<=k
那么他一定比j+h的大,因为s[i+k]>s[j+k]啊
对不对,很简单?不难理解的。
然后这时我们就让i=i+k+1,k=0再次开始重新比较吧!

j也一样。当然我如果j==i了j++.否则就不能再比较了。
最后输出min(i,j)为什么是min(i,j)呢?
语言不大好表达,自己思考思考。当然记住也不难

如此,此题得解!!

代码如下:

#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<stack>
using namespace std;
const int max_n = 1e5 + 100;
const int max_m = 1e5 + 100;
int n, m;
string ss[max_n];

string getmin(string s) {
    int len = s.size();int i = 0, j = 1, k = 0;
    while(i <= len && j <= len && k <= len) {
        if (s[(i + k) % len] == s[(j + k) % len])k++;
        else if (s[(i + k) % len] > s[(j + k) % len])i = i + k + 1, k = 0;
        else if (s[(i + k) % len < s[(j + k) % len]])j = j + k + 1, k = 0;
        if (i == j)j++;
    }return (s + s).substr(min(i, j), len);
}

struct edge
{
    int to, next;
}E[max_n];
int head[max_n];
int cnt = 1;
void add(int from, int to) {
    E[cnt].to = to;
    E[cnt].next = head[from];
    head[from] = cnt++;
}

int res = 0;
stack<int> st;
int dfn[max_n], low[max_n], color[max_n];
int colour = 0, tot = 0;
map<string, int> mp;
void tarjan(int u) {
    dfn[u] = low[u] = ++tot;st.push(u);
    for (int i = head[u];i;i = E[i].next) {
        int v = E[i].to;
        if (!dfn[v]) { tarjan(v);low[u] = min(low[u], low[v]); }
        else if (color[v] == 0)low[u] = min(low[u], dfn[v]);
    }if (dfn[u] != low[u])return;
    colour++;
    while (st.top() != u) {
        color[st.top()] = colour;
        mp[ss[st.top()]]++;
        st.pop();
    }color[st.top()] = colour;mp[ss[st.top()]]++;st.pop();
    for (auto it = mp.begin();it != mp.end();it++)
        res = max(res, (*it).second);
    mp.clear();
}

void solve() {
    for (int i = 1;i <= n;i++)
        if (!dfn[i])tarjan(i);
    cout << res << endl;
}
void init() {
    fill(head, head + n + 10, false);
    cnt = 1;colour = 0;tot = 0;res = 0;
    fill(dfn, dfn + +n + 10, false);
    fill(color, color + n + 10, 0);
    fill(low, low + n + 10, 0);
}

int main() {
    ios::sync_with_stdio(0);
    while (cin >> n >> m) {
        init();
        for (int i = 1;i <= n;i++) {
            cin >> ss[i];
            ss[i] = getmin(ss[i]);
        }for (int i = 1;i <= m;i++) {
            int u, v;cin >> u >> v;
            add(u, v);
        }solve();
    }
}
全部评论

相关推荐

2025-12-25 16:26
已编辑
河北科技学院 Java
勇敢的牛油不服输:2800-300那不等于2500一个月吗兄弟们
点赞 评论 收藏
分享
2025-11-07 03:09
深圳大学 C++
实习秋招做的很差,也想总结一下自己的大学生涯吧。不算太摆,但是很迷。0.大学前高考发挥超常,才来到深大计软。大学前暑期基本上都是玩游戏了。接触了python(李笑来)但是没接触到online&nbsp;judge,也没去多了解编程生态、计算机行业。背了背单词,但是没去规划指标如六级,没制定计划不了了之。1.大一军训时去了校ACM培训,当时dev编译器都不会下载。军训期间积极看B站大学c语言课程。力扣,牛客都是知道的,但是没有成为很好的跳板。第二次培训,看不懂cpp的&nbsp;cin&amp;gt;&amp;gt;,网上搜了也没搞懂,再加上周末跟训得三个多小时,感觉跟不上放弃了。自费报了蓝桥杯,混了省二跟着一些机构课程学习,走的cpp路线。暑假在linux上熟悉vim操作。2.大二朝花夕拾,又去参加ACM训练,跟了一年,寒假都在码&nbsp;带懒标记的线段树。codeforce和力扣赛都在打打(竞赛还是有趣的)。集训队入队周赛打四场,校赛拿金,面试时表现差,说自己想就业,遂挂。当时四月多,2024华为软件精英挑战赛也在打,拿了80名(前64才有三等奖)。蓝桥杯国二。很多晚上跑步来消磨时间。3.大三上修了深大最强的计算机图形学,408找实习,投简历了说自己只有周末有空,遂没在找。也没看牛客真实行情。寒假随便做了个日志器,属于混过去了。当时接到字节的面试(人生处女面),前一天觉都睡不好,很紧张,手撕做的不好,话都说不利索了。面评脏。大三下找实习,cpp选手,没有很好经历、项目,运气好去了学校附近中厂实习。4.大四现在,貌似对开发不上心?没有好的offer(甚至hot100不会做)其实同届好多同学都拿的不错。还有保研C9的。嗯,考研吧。————对自己行为的分析:a.应试教育+应试家庭教育,我的个性是固执、遵规守矩的。b.还有莫名的孤独,明明有很多朋友,但还是没有很好的内驱力,没有坚定的理想。c.自己没有很好的调研、探索和规划能力。大家也可以锐评一下😊
_Matrice_:差不多的性格,不然不会本科时硬杠cpp(那个时候还没有大模型,啃完一整本primer和习题,还是做不出来什么东西),还找不到方向,相比之下学习一些应用层的同学已经能够参考别人的方法做出实用的应用了。学东西,找实习,感觉更多地是出于和别人比较,而不是自我内驱。不过...正如deft所说,人生不需要他人的建议,所以也没有标准化的路径,在能够自食其力的背景下慢慢找到自己的生活方式吧...。另外面试很多时候看运气、眼缘
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务