题意:给你一个字符串,和每个位置可能的字符(没有就可以放任意字符)要求一个排列使得每个位置的字符在可能的字符中,求字典序最小的那个

题解:很容易判断有没有解,建6个点表示从a-f,和源点连边,容量为原串字符出现次数,再建64个点表示给定的位置的每一个状态,和汇点连边,容量为出现次数,如果a-f某个字符在状态中出现过,再把a-f和状态连边,容量inf,但是这只能求可行解,并不是字典序最小,

我们枚举每个位置该放哪个字符(a-f),假设该位置是pos,枚举的字符是x,该位置可能字符的状态是st,现在流量是s->x->st->t,如果这条路上最小流量不是0,我们把这条路往回流1然后,把容量缩小1,判断后面的字符是不是可行,如果可行,那么我们就在该位置放x,(从小到大枚举,贪心的放),

现在有一个问题就是虽然s->x,st->t可能有流量,但是x到st不一定流量,所以我们枚举x到达的每一个状态,然后回流1,再枚举st对应的每个字符,回流1,最后统一增广

还好这题图是个二分图,不然回流可能写死人

虽然我写了当前弧优化,还是没用,不加编译优化会t!!!

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12;
const int N=73+10,maxn=1500+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct edge{
int to,Next,c,cc;
}e[maxn];
int s,t,cnt,head[N],cur[N];
vi v[N],rev[N];
void init()
{
cnt=0;
memset(head,-1,sizeof head);
}
void add(int u,int v,int c)
{
e[cnt].to=v;
e[cnt].c=c;
e[cnt].cc=c;
e[cnt].Next=head[u];
head[u]=cnt++;
e[cnt].to=u;
e[cnt].c=0;
e[cnt].cc=0;
e[cnt].Next=head[v];
head[v]=cnt++;
}
int dis[N];
bool bfs()
{
queue<int>q;
memset(dis,-1,sizeof dis);
dis[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];~i;i=e[i].Next)
{
int y=e[i].to;
if(dis[y]==-1&&e[i].c>0)
{
dis[y]=dis[x]+1;
q.push(y);
}
}
}
return dis[t]!=-1;
}
int dfs(int u,int mx)
{
if(u==t)return mx;
int f;
for(int &i=cur[u];~i;i=e[i].Next)
{
int x=e[i].to;
if(dis[x]==dis[u]+1&&e[i].c>0&&(f=dfs(x,min(mx,e[i].c))))
{
e[i].c-=f;
e[i^1].c+=f;
return f;
}
}
return 0;
}
int maxflow()
{
int ans=0,f;
while(bfs())
{
for(int i=0;i<=t;i++)cur[i]=head[i];
while((f=dfs(s,inf)))ans+=f;
}
return ans;
}
void calcelflow(int be,int en)
{ }
char c[100010],cc[10];
int mask[100010],a[10],num[100];
int id[100][100];
int main()
{
scanf("%s",c);
int n=strlen(c),m;
for(int i=0;i<n;i++)a[c[i]-'a']++;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int id;
scanf("%d%s",&id,cc);id--;
int len=strlen(cc);
for(int j=0;j<len;j++)mask[id]|=(1<<(cc[j]-'a'));
if(!mask[id])mask[id]=(1<<6)-1;
num[mask[id]]++;
}
for(int i=0;i<n;i++)
if(!mask[i])
num[mask[i]=(1<<6)-1]++;
s=6+(1<<6),t=6+(1<<6)+1;
init();
for(int i=0;i<6;i++)id[s][i]=cnt,add(s,i,a[i]);
for(int i=0;i<(1<<6);i++)id[i+6][t]=cnt,add(i+6,t,num[i]);
for(int i=0;i<(1<<6);i++)
for(int j=0;j<6;j++)
if((i>>j)&1)
v[j].pb(i),rev[i].pb(j),
id[j][i+6]=cnt,add(j,i+6,inf);
int ans=maxflow();
for(int i=0;i<n;i++)
{
bool ok=1;
for(int j=0;j<6;j++)
{
if(!((mask[i]>>j)&1))continue;
if(e[id[s][j]+1].c==0||e[id[mask[i]+6][t]+1].c==0)continue;
for(int k=0;k<rev[mask[i]].size();k++)
{
int x=rev[mask[i]][k];
if(e[id[x][mask[i]+6]+1].c!=0&&e[id[s][x]+1].c!=0)
{
int mi=min(e[id[x][mask[i]+6]+1].c,min(e[id[s][x]+1].c,e[id[mask[i]+6][t]+1].c));
e[id[s][x]+1].c-=1;
e[id[x][mask[i]+6]+1].c-=1;
e[id[mask[i]+6][t]+1].c-=1;
e[id[s][x]].c+=1;
e[id[x][mask[i]+6]].c+=1;
e[id[mask[i]+6][t]].c+=1;
ans-=1;
break;
}
}
for(int k=0;k<v[j].size();k++)
{
int x=v[j][k];
if(e[id[j][x+6]+1].c!=0&&e[id[x+6][t]+1].c!=0)
{
int mi=min(e[id[s][j]+1].c,min(e[id[j][x+6]+1].c,e[id[x+6][t]+1].c));
e[id[s][j]+1].c-=1;
e[id[j][x+6]+1].c-=1;
e[id[x+6][t]+1].c-=1;
e[id[s][j]].c+=1;
e[id[j][x+6]].c+=1;
e[id[x+6][t]].c+=1;
ans-=1;
break;
}
}
if(e[id[s][j]].c==0||e[id[j][mask[i]+6]].c==0||e[id[mask[i]+6][t]].c==0)continue;
e[id[s][j]].c--,e[id[j][mask[i]+6]].c--,e[id[mask[i]+6][t]].c--;
ans+=maxflow();
if(ans==n-i-1)
{
c[i]=j+'a';
ok=0;
break;
}
else e[id[s][j]].c++,e[id[j][mask[i]+6]].c++,e[id[mask[i]+6][t]].c++,ans+=maxflow();
}
if(ok)return 0*puts("Impossible");
}
printf("%s\n",c);
return 0;
}
/***********************
bedefead
5
2 e
1 dc
5 b
7 ef
6 ef
***********************/

Educational Codeforces Round 47 (Rated for Div. 2)G. Allowed Letters 网络流的更多相关文章

  1. Educational Codeforces Round 47 (Rated for Div. 2) G. Allowed Letters

    把原字符看成 $X$,每个位置看成 $Y$,每种字符向每个能去的位置连边,就成了一个二分图完美匹配的问题.现要得到字典序最小,那么就枚举每一位要放什么,然后看放完这种字符,剩下的字符的个数和后面能不能 ...

  2. Educational Codeforces Round 39 (Rated for Div. 2) G

    Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...

  3. Educational Codeforces Round 47 (Rated for Div. 2) 题解

    题目链接:http://codeforces.com/contest/1009 A. Game Shopping 题目: 题意:有n件物品,你又m个钱包,每件物品的价格为ai,每个钱包里的前为bi.你 ...

  4. Educational Codeforces Round 47 (Rated for Div. 2) :E. Intercity Travelling

    题目链接:http://codeforces.com/contest/1009/problem/E 解题心得: 一个比较简单的组合数学,还需要找一些规律,自己把方向想得差不多了但是硬是找不到规律,还是 ...

  5. Educational Codeforces Round 47 (Rated for Div. 2) :D. Relatively Prime Graph

    题目链接:http://codeforces.com/contest/1009/problem/D 解题心得: 题意就是给你n个点编号1-n,要你建立m条无向边在两个互质的点之间,最后所有点形成一个连 ...

  6. Educational Codeforces Round 47 (Rated for Div. 2) :C. Annoying Present(等差求和)

    题目链接:http://codeforces.com/contest/1009/problem/C 解题心得: 题意就是一个初始全为0长度为n的数列,m此操作,每次给你两个数x.d,你需要在数列中选一 ...

  7. Educational Codeforces Round 47 (Rated for Div. 2) :B. Minimum Ternary String

    题目链接:http://codeforces.com/contest/1009/problem/B 解题心得: 题意就是给你一个只包含012三个字符的字符串,位置并且逻辑相邻的字符可以相互交换位置,就 ...

  8. Educational Codeforces Round 47 (Rated for Div. 2) :A. Game Shopping

    题目链接:http://codeforces.com/contest/1009/problem/A 解题心得: 题意就是给你两个数列c,a,你需要从c中选择一个子串从a头开始匹配,要求子串中的连续的前 ...

  9. Educational Codeforces Round 47 (Rated for Div. 2)E.Intercity Travelling

    题目链接 大意:一段旅途长度N,中间可能存在N-1个休息站,连续走k长度时,疲劳值为a1+a2+...+aka_1+a_2+...+a_ka1​+a2​+...+ak​,休息后a1a_1a1​开始计, ...

随机推荐

  1. python的数据结构之数字和字符串(四)

    一.数字 Python Number 数据类型用于存储数值.数据类型是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间. Python 支持四种不同的数值类型: 整型( ...

  2. Linux基础命令---gzip

    gzip gzip通过Lempel-ziv算法来压缩文件,压缩的时候保留每个文件的所有者.权限.修改时间.对于符号链接,gzip将会忽略它. 如果压缩的文件名对其文件系统来说太长,则gzip将截断它. ...

  3. Linux服务器配置---ftp用户黑名单

    用户黑白名单 一个Linux主机中会多个用户,而我们希望有些用户不能去访问ftp.ftp服务器可以通过配置文件“/etc/vsftpd/user_list”来设置一个用户列表,这个列表可以是黑名单,也 ...

  4. 查看.mobileprovision 详细信息

    .mobileprovision 用诸如sublime 等工具是无法打开. 可以通过shell命令查看: security cms -D -i 某某.mobileprovision

  5. Winform 出现“Win已停止工作”解决方法

    一.错误描述 错误名称如上.整体错误如下: Win已停止工作 二.解决方法: 1.请以管理员身份运行命令:“netsh winsock reset”,重启电脑后再次尝试运行本工具. 2.使用360安全 ...

  6. torch7入门(安装与使用)

    http://blog.csdn.net/real_myth/article/details/52291636 1.安装与使用 测试系统是ubuntu14.04LTS,默认安装在-/torch,当然我 ...

  7. Python入门之PyCharm中目录directory与包package的区别

    对于Python而言,有一点是要认识明确的,python作为一个相对而言轻量级的,易用的脚本语言(当然其功能并不仅限于此,在此只是讨论该特点),随着程序的增长,可能想要把它分成几个文件,以便逻辑更加清 ...

  8. Servlet过滤器和监听器配置范例

    1,Servlet过滤器 <filter> <filter-name>charset</filter-name> <filter-class>org.g ...

  9. 20145304 刘钦令 Exp2 后门原理与实践

    20145304 刘钦令 Exp2 后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 浏览网页时,或许会触发网站中隐藏的下载代码,将后门程序下载到默认地址. 下载的 ...

  10. 遍历GroupBox上的所有的textbox

    foreach (Control c in groupBox1.Controls) { if (c is TextBox) { //这里写代码逻辑 } } 遍历的时候,需要用Control遍历: 如果 ...